<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather Advisor โ€” Live Forecast & Life Guidance</title>
<style>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box;}
body{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  background:#f5f0e8;
  color:#2c2620;
  min-height:100vh;
  font-size:15px;
  line-height:1.6;
}
.wx-wrap{max-width:960px;margin:0 auto;padding:24px 16px 72px;}
.wx-hero{text-align:center;padding:26px 0 18px;}
.wx-hero h1{font-size:2rem;font-weight:700;color:#2c2620;letter-spacing:-0.5px;}
.wx-hero p{color:#6b6058;margin-top:6px;font-size:0.9rem;}

.wx-search-row{display:flex;gap:10px;flex-wrap:wrap;margin:16px 0 22px;}
.wx-search-row input{
  flex:1;min-width:200px;padding:11px 16px;background:#fffefb;
  border:1.5px solid #d4cdc2;border-radius:10px;font-size:0.95rem;color:#2c2620;outline:none;
}
.wx-search-row input:focus{border-color:#c47c2b;}
.wx-search-row input::placeholder{color:#b0a89e;}
.wx-btn{padding:11px 22px;border:none;border-radius:10px;font-size:0.9rem;font-weight:600;cursor:pointer;transition:opacity 0.2s;white-space:nowrap;}
.wx-btn:hover{opacity:0.88;}
.wx-btn-amber{background:#c47c2b;color:#fff;}
.wx-btn-green{background:#2d7a4f;color:#fff;}

.wx-err{background:#fdf0ee;border:1px solid #e8b4ad;color:#8b2a1e;padding:12px 16px;border-radius:8px;margin-bottom:14px;font-size:0.88rem;display:none;}
.wx-loader{text-align:center;padding:52px 20px;display:none;}
.wx-spinner{width:36px;height:36px;border:3px solid #e2dbd0;border-top-color:#c47c2b;border-radius:50%;animation:wxspin 0.75s linear infinite;margin:0 auto 12px;}
@keyframes wxspin{to{transform:rotate(360deg);}}
.wx-loader p{color:#6b6058;font-size:0.9rem;}

.wx-alerts{display:flex;flex-direction:column;gap:8px;margin-bottom:14px;}
.wx-alert-item{background:#fff8ec;border:1px solid #f0c85a;color:#7a4d10;padding:9px 14px;border-radius:8px;font-size:0.84rem;display:flex;gap:8px;align-items:flex-start;}

.wx-sec{font-size:0.68rem;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;color:#9e9088;margin:26px 0 10px;padding-bottom:6px;border-bottom:1px solid #e2dbd0;}

.wx-cur-card{background:#fffefb;border:1px solid #e2dbd0;border-radius:12px;padding:20px;}
.wx-cur-header{display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:10px;margin-bottom:18px;}
.wx-cur-header h2{font-size:1.25rem;font-weight:700;}
.wx-cur-header .wx-sub{font-size:0.78rem;color:#9e9088;margin-top:3px;}
.wx-date-pill{background:#fdf3e3;border:1px solid #f0c57a;color:#c47c2b;padding:5px 12px;border-radius:20px;font-size:0.78rem;font-weight:600;white-space:nowrap;flex-shrink:0;}
.wx-stats{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:9px;}
.wx-stat{background:#f5f0e8;border:1px solid #e2dbd0;border-radius:8px;padding:12px 10px;text-align:center;}
.wx-stat .wx-si{font-size:1.5rem;margin-bottom:4px;}
.wx-stat .wx-sl{font-size:0.66rem;color:#9e9088;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;}
.wx-stat .wx-sv{font-size:1.15rem;font-weight:700;margin-top:2px;}
.wx-stat .wx-ss{font-size:0.68rem;color:#6b6058;margin-top:1px;}

.wx-nearby-row{display:flex;gap:8px;flex-wrap:wrap;}
.wx-nearby-chip{
  background:#fffefb;border:1px solid #d4cdc2;color:#2c2620;
  padding:8px 16px;border-radius:20px;font-size:0.83rem;font-weight:600;
  cursor:pointer;transition:border-color 0.2s,background 0.2s;
}
.wx-nearby-chip:hover{border-color:#c47c2b;background:#fdf3e3;}
.wx-nearby-loading{font-size:0.82rem;color:#9e9088;}

.wx-hourly-scroll{overflow-x:auto;padding-bottom:6px;}
.wx-hourly-scroll::-webkit-scrollbar{height:4px;}
.wx-hourly-scroll::-webkit-scrollbar-thumb{background:#d4cdc2;border-radius:2px;}
.wx-hourly-row{display:flex;gap:8px;min-width:max-content;}
.wx-hcard{width:70px;background:#fffefb;border:1px solid #e2dbd0;border-radius:8px;padding:10px 6px;text-align:center;flex-shrink:0;}
.wx-hcard.wx-now{border-color:#c47c2b;background:#fdf3e3;}
.wx-hcard .wx-ht{font-size:0.67rem;font-weight:700;color:#6b6058;}
.wx-hcard .wx-hi{font-size:1.35rem;margin:4px 0;}
.wx-hcard .wx-hv{font-size:0.9rem;font-weight:700;}
.wx-hcard .wx-hr{font-size:0.62rem;color:#2563b0;margin-top:2px;min-height:13px;}

.wx-fc-list{display:flex;flex-direction:column;gap:7px;}
.wx-fc-row{display:grid;grid-template-columns:118px 42px 1fr 64px;align-items:center;gap:10px;background:#fffefb;border:1px solid #e2dbd0;border-radius:8px;padding:11px 14px;transition:border-color 0.2s;}
.wx-fc-row:hover{border-color:#d4cdc2;}
.wx-fc-day{font-size:0.88rem;font-weight:700;}
.wx-fc-dt{font-size:0.7rem;color:#9e9088;margin-top:1px;}
.wx-fc-icon{font-size:1.5rem;}
.wx-fc-mid{display:flex;flex-direction:column;gap:4px;}
.wx-fc-desc{font-size:0.76rem;color:#6b6058;}
.wx-fc-bar{height:3px;background:#e2dbd0;border-radius:2px;overflow:hidden;}
.wx-fc-fill{height:100%;background:#2563b0;border-radius:2px;}
.wx-fc-temps{text-align:right;font-size:0.88rem;font-weight:700;white-space:nowrap;}
.wx-thi{color:#c0392b;}
.wx-tlo{color:#2563b0;}

.wx-tips-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:12px;}
.wx-tip{border-radius:10px;padding:16px;border-left:4px solid;}
.wx-tip h4{font-size:0.8rem;font-weight:700;text-transform:uppercase;letter-spacing:0.7px;margin-bottom:8px;display:flex;align-items:center;gap:6px;}
.wx-tip p{font-size:0.85rem;line-height:1.7;color:#4a4038;margin-bottom:6px;}
.wx-tip p:last-child{margin-bottom:0;}
.wx-tip ul{margin:6px 0 0 18px;padding:0;}
.wx-tip li{font-size:0.83rem;line-height:1.65;color:#4a4038;margin-bottom:3px;}
.wx-tip-cloth{background:#fff5f5;border-color:#e07070;}.wx-tip-cloth h4{color:#a02020;}
.wx-tip-home{background:#edf7f2;border-color:#3a9060;}.wx-tip-home h4{color:#1e5a38;}
.wx-tip-garden{background:#f3f0fa;border-color:#7c5db0;}.wx-tip-garden h4{color:#5a3f8a;}
.wx-tip-travel{background:#eef4fd;border-color:#4080c8;}.wx-tip-travel h4{color:#1a4a80;}
.wx-tip-car{background:#fff9ee;border-color:#d4903a;}.wx-tip-car h4{color:#8a5010;}
.wx-tip-health{background:#fef0f6;border-color:#c85a8e;}.wx-tip-health h4{color:#9c2d63;}
.wx-tip-outdoor{background:#f0f9ec;border-color:#6fa03a;}.wx-tip-outdoor h4{color:#4a6e1e;}
.wx-tip-severe{background:#fdeeee;border-color:#c0392b;}.wx-tip-severe h4{color:#a02020;}
.wx-tip-tools{background:#eef7f7;border-color:#2a9d9d;}.wx-tip-tools h4{color:#1a6a6a;}
.wx-tip-safe{background:#edf7f2;border-color:#3a9060;}.wx-tip-safe h4{color:#1e5a38;}

.wx-extreme-section{margin-top:34px;}
.wx-extreme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px;}
.wx-extreme-card{background:#fffefb;border:1px solid #e2dbd0;border-radius:10px;padding:15px;}
.wx-extreme-tag{display:inline-block;font-size:0.65rem;font-weight:700;letter-spacing:0.5px;background:#2c2620;color:#fdf3e3;padding:3px 9px;border-radius:10px;margin-bottom:8px;text-transform:uppercase;}
.wx-extreme-name{font-size:0.95rem;font-weight:700;color:#2c2620;}
.wx-extreme-loc{font-size:0.74rem;color:#9e9088;margin-top:1px;margin-bottom:8px;}
.wx-extreme-temp{font-size:1.6rem;font-weight:700;color:#c47c2b;}
.wx-extreme-desc{font-size:0.78rem;color:#6b6058;margin-top:4px;}

footer{text-align:center;color:#b0a89e;padding:28px 16px 18px;font-size:0.76rem;}
.wx-footer-links{margin-top:8px;}
.wx-footer-links a{color:#b0a89e;text-decoration:underline;margin:0 6px;}
.wx-footer-links a:hover{color:#9e9088;}

.wx-about-section{background:#fffefb;border:1px solid #e2dbd0;border-radius:14px;padding:20px 24px;margin:28px 0 0;}
.wx-about-inner{display:flex;align-items:flex-start;gap:16px;max-width:960px;margin:0 auto;}
.wx-about-icon{font-size:2rem;flex-shrink:0;margin-top:2px;}
.wx-about-body h3{font-size:0.95rem;font-weight:700;color:#2c2620;margin-bottom:6px;}
.wx-about-body p{font-size:0.82rem;color:#6b6058;line-height:1.65;margin-bottom:10px;}
.wx-about-body p a{color:#2563b0;text-decoration:none;}
.wx-about-body p a:hover{text-decoration:underline;}
.wx-about-badges{display:flex;flex-wrap:wrap;gap:8px;}
.wx-about-badges span{font-size:0.72rem;font-weight:600;background:#f5f0e8;border:1px solid #e2dbd0;color:#6b6058;padding:3px 10px;border-radius:20px;}

@media(max-width:600px){
  .wx-fc-row{grid-template-columns:80px 34px 1fr 54px;}
  .wx-stats{grid-template-columns:repeat(3,1fr);}
}
@media(max-width:480px){
  .wx-about-inner{flex-direction:column;gap:8px;}
}
</style>
</head>
<body>

<div class="wx-wrap">
  <div class="wx-hero">
    <h1>๐ŸŒค Weather Advisor</h1>
    <p>Live forecast ยท Hourly outlook ยท 10-day planner ยท Practical weather guidance</p>
  </div>

  <div class="wx-search-row">
    <input type="text" id="wxCityInput" placeholder="Search any city โ€” e.g. New York, London, Tokyo..." />
    <button class="wx-btn wx-btn-amber" onclick="wxSearchCity()">Search</button>
    <button class="wx-btn wx-btn-green" onclick="wxDetectLocation()">๐Ÿ“ My Location</button>
  </div>

  <div class="wx-err" id="wxErrBox"></div>
  <div class="wx-loader" id="wxLoaderBox"><div class="wx-spinner"></div><p id="wxLoaderMsg">Loading...</p></div>
  <div id="wxContent"></div>

  <!-- โ”€โ”€ GLOBAL EXTREME WEATHER (persistent, independent of searched city) โ”€โ”€ -->
  <div class="wx-extreme-section">
    <div class="wx-sec">๐ŸŒ Global Extreme Weather Watch</div>
    <p style="font-size:0.8rem;color:#6b6058;margin-bottom:12px;">
      Live current conditions at some of Earth's most extreme climate locations, for context and comparison.
    </p>
    <div id="wxExtreme"><p class="wx-nearby-loading">Loading global extremes...</p></div>
  </div>
</div>

<!-- โ”€โ”€ ABOUT SECTION โ”€โ”€ -->
<div class="wx-about-section">
  <div class="wx-about-inner">
    <div class="wx-about-icon">๐ŸŒค๏ธ</div>
    <div class="wx-about-body">
      <h3>About This Tool</h3>
      <p>
        <strong>Weather Advisor</strong> is a free, real-time weather tool powered by
        <a href="https://open-meteo.com" target="_blank" rel="noopener">Open-Meteo</a>,
        <a href="https://ipapi.co" target="_blank" rel="noopener">ipapi.co</a>, and
        <a href="https://www.bigdatacloud.com" target="_blank" rel="noopener">BigDataCloud</a>.
        No sign-up required. No data stored. Your location is used only to fetch
        your local forecast and is never saved or shared.
      </p>
      <div class="wx-about-badges">
        <span>โœ… Always Free</span>
        <span>๐Ÿ”’ No Account Needed</span>
        <span>๐Ÿ“ก Real-Time Data</span>
        <span>๐ŸŒ Any City Worldwide</span>
      </div>
    </div>
  </div>
</div>

<footer>
  Powered by Open-Meteo, ipapi.co &amp; BigDataCloud โ€” data refreshed in real time
  <div class="wx-footer-links">
    <a href="privacy.html" target="_blank">Privacy Policy</a>
    &middot;
    <a href="about.html" target="_blank">About Us</a>
  </div>
</footer>

<script>
var WX_WC = {
  0:{d:`Clear`,i:`&#9728;`},1:{d:`Mostly Clear`,i:`&#127780;`},
  2:{d:`Partly Cloudy`,i:`&#9925;`},3:{d:`Overcast`,i:`&#9729;`},
  45:{d:`Foggy`,i:`&#127787;`},48:{d:`Freezing Fog`,i:`&#127787;`},
  51:{d:`Light Drizzle`,i:`&#127782;`},53:{d:`Drizzle`,i:`&#127782;`},
  55:{d:`Heavy Drizzle`,i:`&#127783;`},61:{d:`Light Rain`,i:`&#127783;`},
  63:{d:`Moderate Rain`,i:`&#127783;`},65:{d:`Heavy Rain`,i:`&#9928;`},
  71:{d:`Light Snow`,i:`&#127784;`},73:{d:`Snow`,i:`&#10052;`},
  75:{d:`Heavy Snow`,i:`&#10052;`},77:{d:`Snow Grains`,i:`&#127784;`},
  80:{d:`Rain Showers`,i:`&#127782;`},81:{d:`Heavy Showers`,i:`&#127783;`},
  82:{d:`Violent Showers`,i:`&#9928;`},85:{d:`Snow Showers`,i:`&#127784;`},
  86:{d:`Heavy Snow Showers`,i:`&#10052;`},95:{d:`Thunderstorm`,i:`&#9928;`},
  96:{d:`T-Storm + Hail`,i:`&#9928;`},99:{d:`Severe T-Storm`,i:`&#9928;`}
};
function wxWc(code){ return WX_WC[code] || {d:`Unknown`,i:`?`}; }

function wxShowErr(msg){
  var b=document.getElementById(`wxErrBox`);
  b.textContent=`\u26A0\uFE0F `+msg;b.style.display=`block`;wxHideLoader();
}
function wxClearErr(){ document.getElementById(`wxErrBox`).style.display=`none`; }
function wxShowLoader(msg){
  wxClearErr();
  document.getElementById(`wxContent`).innerHTML=``;
  document.getElementById(`wxLoaderMsg`).textContent=msg||`Loading...`;
  document.getElementById(`wxLoaderBox`).style.display=`block`;
}
function wxHideLoader(){ document.getElementById(`wxLoaderBox`).style.display=`none`; }
function wxToC(c){ return Math.round(c); }
function wxToKmh(kmh){ return Math.round(kmh); }
function wxUvLabel(uv){
  if(uv==null)return``;
  if(uv>=11)return`Extreme`;if(uv>=8)return`Very High`;
  if(uv>=6)return`High`;if(uv>=3)return`Moderate`;return`Low`;
}
var WX_DIRS=[`N`,`NE`,`E`,`SE`,`S`,`SW`,`W`,`NW`];
function wxWindDir(deg){ return WX_DIRS[Math.round(deg/45)%8]||``; }

function wxDewPoint(tC,rh){
  var a=17.27,b=237.7;
  var alpha=((a*tC)/(b+tC))+Math.log(Math.max(rh,1)/100);
  return (b*alpha)/(a-alpha);
}
function wxHeatIndexC(tC,rh){
  var tF=tC*9/5+32;
  if(tF<80) return null;
  var hi=-42.379+2.04901523*tF+10.14333127*rh-0.22475541*tF*rh
    -0.00683783*tF*tF-0.05481717*rh*rh+0.00122874*tF*tF*rh
    +0.00085282*tF*rh*rh-0.00000199*tF*tF*rh*rh;
  return (hi-32)*5/9;
}
function wxWindChillC(tC,windKmh){
  if(tC>10||windKmh<=4.8) return null;
  return 13.12+0.6215*tC-11.37*Math.pow(windKmh,0.16)+0.3965*tC*Math.pow(windKmh,0.16);
}

function wxDetectLocation(){
  wxShowLoader(`Detecting your location...`);
  fetch(`https://ipapi.co/json/`)
    .then(function(r){return r.json();})
    .then(function(d){
      if(d.error) throw new Error(d.reason||`Location failed`);
      if(!d.latitude) throw new Error(`No coordinates found`);
      wxFetchWeather(d.latitude,d.longitude,d.city||`Unknown`,d.region||``,d.country_name||``,d.ip||``);
    })
    .catch(function(e){wxShowErr(`Auto-location failed. Please search a city manually. (`+e.message+`)`);});
}

function wxSearchCity(){
  var name=document.getElementById(`wxCityInput`).value.trim();
  if(!name){wxShowErr(`Please enter a city name.`);return;}
  wxShowLoader(`Searching for "`+name+`"...`);wxClearErr();
  fetch(`https://geocoding-api.open-meteo.com/v1/search?name=`+encodeURIComponent(name)+`&count=1&language=en&format=json`)
    .then(function(r){return r.json();})
    .then(function(d){
      if(!d.results||!d.results.length) throw new Error(`"`+name+`" not found. Try a different spelling.`);
      var p=d.results[0];
      wxFetchWeather(p.latitude,p.longitude,p.name,p.admin1||``,p.country||``,``);
    })
    .catch(function(e){wxShowErr(e.message);});
}

function wxFetchWeather(lat,lon,city,state,country,ip){
  wxShowLoader(`Loading forecast...`);
  var url=`https://api.open-meteo.com/v1/forecast`
    +`?latitude=`+lat+`&longitude=`+lon
    +`&current=temperature_2m,relative_humidity_2m,apparent_temperature,is_day,weather_code,wind_speed_10m,wind_direction_10m,surface_pressure`
    +`&hourly=temperature_2m,weather_code,precipitation_probability,apparent_temperature,visibility`
    +`&daily=weather_code,temperature_2m_max,temperature_2m_min,precipitation_probability_max,wind_speed_10m_max,uv_index_max,sunrise,sunset`
    +`&timezone=auto&forecast_days=10`;
  fetch(url)
    .then(function(r){return r.json();})
    .then(function(d){
      if(!d.current) throw new Error(`No weather data returned.`);
      wxHideLoader();wxRenderPage(d,lat,lon,city,state,country,ip);
    })
    .catch(function(e){wxShowErr(`Could not load weather: `+e.message);});
}

/* โ”€โ”€ Destination point at given bearing/distance (spherical earth) โ”€โ”€ */
function wxDestPoint(lat,lon,bearingDeg,distKm){
  var R=6371;
  var brng=bearingDeg*Math.PI/180;
  var lat1=lat*Math.PI/180,lon1=lon*Math.PI/180;
  var lat2=Math.asin(Math.sin(lat1)*Math.cos(distKm/R)+Math.cos(lat1)*Math.sin(distKm/R)*Math.cos(brng));
  var lon2=lon1+Math.atan2(Math.sin(brng)*Math.sin(distKm/R)*Math.cos(lat1),Math.cos(distKm/R)-Math.sin(lat1)*Math.sin(lat2));
  return [lat2*180/Math.PI,lon2*180/Math.PI];
}

/* โ”€โ”€ Load 5 nearby cities around the searched location โ”€โ”€ */
function wxLoadNearbyCities(lat,lon,excludeName){
  var box=document.getElementById(`wxNearby`);
  if(!box) return;
  var bearings=[0,72,144,216,288];
  var dist=70;
  var points=bearings.map(function(b){ return wxDestPoint(lat,lon,b,dist); });
  var calls=points.map(function(p){
    var url=`https://api.bigdatacloud.net/data/reverse-geocode-client?latitude=`+p[0]+`&longitude=`+p[1]+`&localityLanguage=en`;
    return fetch(url).then(function(r){return r.json();}).then(function(d){
      var name=d.city||d.locality||d.principalSubdivision||``;
      return {name:name,country:d.countryName||``,lat:p[0],lon:p[1]};
    }).catch(function(){ return null; });
  });
  Promise.all(calls).then(function(results){
    var seen={};
    if(excludeName) seen[excludeName.toLowerCase()]=true;
    var chips=``;
    var count=0;
    for(var i=0;i<results.length;i++){
      var r=results[i];
      if(!r||!r.name) continue;
      var key=r.name.toLowerCase();
      if(seen[key]) continue;
      seen[key]=true;
      chips+=`<div class="wx-nearby-chip" onclick="wxFetchWeather(`+r.lat+`,`+r.lon+`,'`+r.name.replace(/'/g,``)+`','','`+r.country.replace(/'/g,``)+`','')">๐Ÿ“ `+r.name+(r.country?`, `+r.country:``)+`</div>`;
      count++;
    }
    box.innerHTML = count>0 ? chips : `<p class="wx-nearby-loading">No nearby cities found.</p>`;
  });
}

function wxRenderPage(data,lat,lon,city,state,country,ip){
  var cur=data.current,hrly=data.hourly,daily=data.daily;
  var info=wxWc(cur.weather_code),now=new Date(cur.time);
  var uv0=daily.uv_index_max[0]||0;
  var rain0=daily.precipitation_probability_max[0]||0;
  var wnd0=daily.wind_speed_10m_max[0]||0;
  var todayStr=now.toLocaleDateString(`en-US`,{weekday:`long`,month:`long`,day:`numeric`,year:`numeric`});
  var sr=`N/A`,ss=`N/A`;
  if(daily.sunrise[0]) sr=new Date(daily.sunrise[0]).toLocaleTimeString(`en-US`,{hour:`numeric`,minute:`2-digit`});
  if(daily.sunset[0])  ss=new Date(daily.sunset[0]).toLocaleTimeString(`en-US`,{hour:`numeric`,minute:`2-digit`});
  var locStr=city;
  if(state) locStr+=`, `+state;
  if(country&&country!==`United States`) locStr+=`, `+country;

  var html=``;

  // Quick alert banner
  var quickAlerts=[];
  if(uv0>=8) quickAlerts.push(`&#9728; Very high UV today (`+uv0+`) โ€” wear SPF 30+ if going outdoors.`);
  if(rain0>=65) quickAlerts.push(`&#127783; `+rain0+`% chance of rain today โ€” don't forget an umbrella.`);
  if(wxToKmh(wnd0)>=48) quickAlerts.push(`&#128168; Gusty winds up to `+wxToKmh(wnd0)+` km/h โ€” secure loose items outdoors.`);
  if(quickAlerts.length){
    html+=`<div class="wx-alerts">`;
    for(var a=0;a<quickAlerts.length;a++) html+=`<div class="wx-alert-item"><span>&#9889;</span><span>`+quickAlerts[a]+`</span></div>`;
    html+=`</div>`;
  }

  // Current conditions
  html+=`<div class="wx-sec">Current Conditions</div>`;
  html+=`<div class="wx-cur-card">`;
  html+=`<div class="wx-cur-header">`;
  html+=`<div><h2>&#128205; `+locStr+`</h2>`;
  if(ip) html+=`<div class="wx-sub">IP detected: `+ip+`</div>`;
  html+=`<div class="wx-sub" style="margin-top:5px;font-size:0.82rem;color:#6b6058;">`+todayStr+`</div>`;
  html+=`</div>`;
  html+=`<div class="wx-date-pill">`+info.i+` `+info.d+`</div>`;
  html+=`</div>`;
  html+=`<div class="wx-stats">`;
  html+=wxStat(`&#127777;`,`Temperature`,wxToC(cur.temperature_2m)+`&deg;C`,`Feels like `+wxToC(cur.apparent_temperature)+`&deg;C`);
  html+=wxStat(`&#128167;`,`Humidity`,cur.relative_humidity_2m+`%`,cur.relative_humidity_2m>75?`Humid`:cur.relative_humidity_2m<30?`Dry`:`Comfortable`);
  html+=wxStat(`&#128168;`,`Wind`,wxToKmh(cur.wind_speed_10m)+` km/h`,wxWindDir(cur.wind_direction_10m||0));
  html+=wxStat(`&#128262;`,`UV Index`,uv0,wxUvLabel(uv0));
  html+=wxStat(`&#127765;`,`Sunrise`,sr,`Sunset `+ss);
  html+=wxStat(`&#127783;`,`Rain Chance`,rain0+`%`,`Today`);
  html+=`</div></div>`;

  // Nearby cities
  html+=`<div class="wx-sec">Nearby Cities</div>`;
  html+=`<div class="wx-nearby-row" id="wxNearby"><p class="wx-nearby-loading">Finding nearby cities...</p></div>`;

  // Hourly
  var si=0;
  for(var k=0;k<hrly.time.length;k++){if(new Date(hrly.time[k])>=now){si=k;break;}}
  html+=`<div class="wx-sec">Hourly Outlook &mdash; Next 24 Hours</div>`;
  html+=`<div class="wx-hourly-scroll"><div class="wx-hourly-row">`;
  for(var h=si;h<si+24&&h<hrly.time.length;h++){
    var ht=new Date(hrly.time[h]);
    var hlabel=(h===si)?`Now`:ht.toLocaleTimeString(`en-US`,{hour:`numeric`});
    var hi2=wxWc(hrly.weather_code[h]);
    var hrp=hrly.precipitation_probability[h]||0;
    html+=`<div class="wx-hcard`+(h===si?` wx-now`:``)+`"><div class="wx-ht">`+hlabel+`</div><div class="wx-hi">`+hi2.i+`</div><div class="wx-hv">`+wxToC(hrly.temperature_2m[h])+`&deg;</div><div class="wx-hr">`+(hrp>5?`&#128167;`+hrp+`%`:``)+`</div></div>`;
  }
  html+=`</div></div>`;

  // 10-Day forecast
  var DNAMES=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`];
  var MNAMES=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];
  html+=`<div class="wx-sec">10-Day Forecast</div>`;
  html+=`<div class="wx-fc-list">`;
  for(var i=0;i<daily.time.length;i++){
    var fd=new Date(daily.time[i]+`T12:00:00`);
    var fdayLabel=i===0?`Today`:i===1?`Tomorrow`:DNAMES[fd.getDay()];
    var fdateLabel=MNAMES[fd.getMonth()]+` `+fd.getDate();
    var fi2=wxWc(daily.weather_code[i]);
    var frp=daily.precipitation_probability_max[i]||0;
    var fhi=wxToC(daily.temperature_2m_max[i]);
    var flo=wxToC(daily.temperature_2m_min[i]);
    html+=`<div class="wx-fc-row"><div><div class="wx-fc-day">`+fdayLabel+`</div><div class="wx-fc-dt">`+fdateLabel+`</div></div>`;
    html+=`<div class="wx-fc-icon">`+fi2.i+`</div>`;
    html+=`<div class="wx-fc-mid"><div class="wx-fc-desc">`+fi2.d+(frp>0?` &middot; &#128167;`+frp+`%`:``)+`</div>`;
    html+=`<div class="wx-fc-bar"><div class="wx-fc-fill" style="width:`+frp+`%"></div></div></div>`;
    html+=`<div class="wx-fc-temps"><span class="wx-thi">`+fhi+`&deg;</span> / <span class="wx-tlo">`+flo+`&deg;</span></div></div>`;
  }
  html+=`</div>`;

  // Nine guidance sections
  var sections=wxBuildSections(cur,daily,hrly,si);
  html+=`<div class="wx-sec">Weather Guidance</div>`;
  html+=`<div class="wx-tips-grid">`;
  for(var t2=0;t2<sections.length;t2++){
    html+=`<div class="wx-tip wx-tip-`+sections[t2][0]+`"><h4>`+sections[t2][1]+`</h4>`+sections[t2][2]+`</div>`;
  }
  html+=`</div>`;

  document.getElementById(`wxContent`).innerHTML=html;
  wxLoadNearbyCities(lat,lon,city);
}

function wxStat(icon,label,val,sub){
  return `<div class="wx-stat"><div class="wx-si">`+icon+`</div>`
    +`<div class="wx-sl">`+label+`</div>`
    +`<div class="wx-sv">`+val+`</div>`
    +`<div class="wx-ss">`+sub+`</div></div>`;
}
function wxLi(items){
  var s=`<ul>`;
  for(var i=0;i<items.length;i++) s+=`<li>`+items[i]+`</li>`;
  return s+`</ul>`;
}

function wxBuildSections(cur,daily,hrly,si){
  var t=cur.temperature_2m;
  var feels=cur.apparent_temperature;
  var humid=cur.relative_humidity_2m;
  var code=cur.weather_code;
  var uv=daily.uv_index_max[0]||0;
  var rain=daily.precipitation_probability_max[0]||0;
  var wndKmh=daily.wind_speed_10m_max[0]||0;
  var pressure=cur.surface_pressure||null;
  var visibilityM=(hrly.visibility&&hrly.visibility[si]!=null)?hrly.visibility[si]:null;
  var isRain=[51,53,55,61,63,65,80,81,82,95,96,99].indexOf(code)>=0;
  var isSnow=[71,73,75,77,85,86].indexOf(code)>=0;
  var isStorm=[95,96,99].indexOf(code)>=0;
  var isFog=[45,48].indexOf(code)>=0;

  /* โ”€โ”€ 1. Weather & Clothing โ”€โ”€ */
  var clothP,clothL=[];
  if(t>=35){
    clothP=`Very hot conditions, feels like `+Math.round(feels)+`ยฐC. Prioritize staying cool and limiting sun exposure.`;
    clothL=[`Choose breathable cotton or linen in light colors to reflect heat`,`Wide-brim hat, sunglasses, and SPF 50+ sunscreen, reapplied every 2 hours`,`Avoid prolonged outdoor exposure between 12โ€“3pm`,`Carry a portable fan or cooling towel`];
  } else if(t>=28){
    clothP=`Warm weather calls for light, breathable clothing.`;
    clothL=[`Short sleeves, shorts, or a light dress in quick-dry fabric`,`Pack a spare top if you'll be sweating heavily`,`Bring a light layer for air-conditioned spaces`];
  } else if(t>=20){
    clothP=`Comfortable temperature โ€” the most flexible range for dressing.`;
    clothL=[`Long sleeves, a light hoodie, or a T-shirt all work well`,`Layer up for larger morning/evening temperature swings`,`Choose quick-dry fabric for exercise or extended outdoor time`];
  } else if(t>=12){
    clothP=`Mildly cool โ€” day/night temperature swings matter most here.`;
    clothL=[`Three-layer approach: long sleeve, light sweater, and a jacket`,`Add a scarf for morning and evening outings`,`Humidity of `+humid+`% will make it feel cooler than the thermometer suggests`];
  } else if(t>=0){
    clothP=`Cold conditions, feels like `+Math.round(feels)+`ยฐC. Bundle up properly.`;
    clothL=[`Heavy coat, sweater, and thermal base layer`,`Gloves, hat, and scarf are all essential`,`Choose slip-resistant, insulated footwear โ€” roads may be icy`];
  } else {
    clothP=`Severe cold โ€” minimize skin exposure and dress in full winter gear.`;
    clothL=[`Down jacket or heavy parka with a thermal base layer`,`Gloves, hat, face covering, and scarf are all required`,`Waterproof, slip-resistant winter boots for icy pavement`];
  }
  if(isRain) clothL.push(`With rain expected, bring an umbrella or wear a waterproof shell`);
  if(isSnow) clothL.push(`Snow is expected โ€” wear waterproof, slip-resistant boots`);
  if(wndKmh>=40) clothL.push(`Winds are strong (gusts to `+Math.round(wndKmh)+`km/h) โ€” secure hats with a strap or chin tie`);

  /* โ”€โ”€ 2. Weather & Home โ”€โ”€ */
  var homeP,homeL=[];
  if(humid>=78){
    homeP=`High humidity (`+humid+`%) can make indoor spaces feel muggy โ€” watch for excess moisture.`;
    homeL=[`Run a dehumidifier or your AC's dry mode, especially in closets and basements`,`Air out linens and clothing regularly to prevent mildew`,`Ventilate when possible, but keep windows closed during rain to avoid moisture buildup`];
  } else if(humid<=30){
    homeP=`Dry air (`+humid+`%) indoors โ€” keep an eye on hydration for your home and yourself.`;
    homeL=[`Use a humidifier to keep indoor humidity around 40โ€“60%`,`Wipe down wood furniture and flooring regularly to prevent cracking`,`Misting houseplants can help maintain ambient humidity`];
  } else {
    homeP=`Comfortable indoor humidity โ€” a good day to ventilate.`;
    homeL=[`Open windows for 15โ€“30 minutes, 2โ€“3 times today for fresh air`,`Check window seals and weatherstripping ahead of seasonal changes`];
  }
  if(t>=30) homeL.push(`Set the AC to 26โ€“28ยฐC and pair with a fan for efficient, energy-saving cooling`);
  if(t<=5) homeL.push(`Check door/window seals and heating system function to keep out drafts`);
  if(isStorm) homeL.push(`Unplug non-essential electronics during thunderstorms to protect against power surges`);
  if(wndKmh>=50) homeL.push(`Secure balcony items, patio furniture, and anything loose on rooftops or porches`);

  /* โ”€โ”€ 3. Weather & Garden โ”€โ”€ */
  var gardenP,gardenL=[];
  if(isStorm){
    gardenP=`Thunderstorms can damage garden plants โ€” a little prep now avoids losses later.`;
    gardenL=[`Move potted plants under cover or indoors to prevent stem damage`,`Check drainage in flower beds and gutters to prevent root rot from standing water`,`Stake tall or fragile plants (tomatoes, climbing roses)`,`After the storm, inspect for broken branches and trim clean to prevent infection`];
  } else if(isSnow){
    gardenP=`Snow requires protecting tender plants and outdoor plumbing.`;
    gardenL=[`Cover cold-sensitive shrubs and perennials with frost cloth or straw`,`Brush heavy snow off branches to prevent breakage`,`Insulate outdoor spigots and hoses to prevent freeze damage`,`Move potted plants indoors โ€” frozen soil can damage roots`];
  } else if(isRain||rain>=60){
    gardenP=``+rain+`% chance of rain โ€” a good day to skip watering, but watch for pooling.`;
    gardenL=[`Hold off on manual watering; rainfall should cover most plant needs`,`Check that beds and lawns are draining properly`,`Temporarily cover newly planted seedlings to prevent soil erosion`,`After rain, weeds pull more easily from softened soil`];
  } else if(t>=32){
    gardenP=`High heat speeds up transpiration โ€” plants will need more water.`;
    gardenL=[`Water in early morning or evening to reduce evaporation and leaf scorch`,`Mulch shallow-rooted and newly planted specimens to retain soil moisture`,`Increase lawn watering frequency to prevent dry, browning patches`,`Hold off on fertilizing or pruning โ€” plants recover slowly in extreme heat`];
  } else if(t<=0){
    gardenP=`Freezing temperatures put outdoor plants at frost risk.`;
    gardenL=[`Cover frost-sensitive plants before nightfall`,`Stop fertilizing and heavy watering โ€” frozen, waterlogged roots are vulnerable`,`Drain outdoor water features and irrigation lines to prevent pipe damage`,`Anti-desiccant spray can help protect evergreens from cold injury`];
  } else if(uv>=8){
    gardenP=`Strong UV is great for sun-loving plants, but shade new transplants.`;
    gardenL=[`Use shade cloth over newly transplanted or young seedlings`,`Good conditions for pruning, weeding, and routine fertilizing`,`Water in early morning โ€” droplets on leaves can magnify sunlight and scorch foliage`];
  } else if(wndKmh>=40){
    gardenP=`Strong winds put tall plants and new trees at risk of toppling.`;
    gardenL=[`Check and reinforce stakes and ties on newly planted trees`,`Bring in or secure lightweight pots, ornaments, and umbrellas`,`Inspect climbing plants and trellises to ensure they're firmly anchored`];
  } else {
    gardenP=`Mild conditions โ€” an ideal window for general garden maintenance.`;
    gardenL=[`Good day for planting, transplanting, fertilizing, and pruning`,`Check lawn moisture to decide if irrigation is needed`,`Clear fallen leaves and turn over garden bed soil`];
  }

  /* โ”€โ”€ 4. Weather & Travel โ”€โ”€ */
  var travelP,travelL=[];
  if(isStorm){
    travelP=`Thunderstorms are likely to disrupt travel plans today.`;
    travelL=[`Check flight status โ€” thunderstorms are a leading cause of ground stops and delays`,`Avoid unnecessary road trips; steer well clear of flooded roads`,`Allow extra buffer time for public transit disruptions`];
  } else if(isSnow){
    travelP=`Snow raises the risk of road and flight delays.`;
    travelL=[`Check for winter travel advisories and possible road closures`,`Build in significant extra time for any trip`,`Consider rail over short-haul flights, which are more prone to snow delays`];
  } else if(isRain||rain>=50){
    travelP=`With a `+rain+`% chance of rain, expect minor delays.`;
    travelL=[`Pack a compact umbrella or rain shell`,`Some airports apply ground stops during heavy rain โ€” check status before heading out`,`Allow extra buffer time for slower road and transit traffic`];
  } else if(isFog){
    travelP=`Fog significantly reduces visibility for all forms of travel.`;
    travelL=[`Flight delays and diversions are common in dense fog โ€” check status before departing`,`Drive with low beams and increase following distance`,`Allow extra time for early-morning travel when fog is often thickest`];
  } else if(wndKmh>=45){
    travelP=`Strong winds (gusts to `+Math.round(wndKmh)+`km/h) may affect travel.`;
    travelL=[`Turbulence and delays are possible for flights today`,`High-profile vehicles may face bridge or highway restrictions`,`Secure roof racks and cargo before any road trip`];
  } else if(t>=15&&t<=26&&rain<30){
    travelP=`Great conditions for travel of any kind.`;
    travelL=[`Ideal weather for road trips, walking commutes, or cycling to your destination`,`Minimal weather-related disruptions expected`,`Still worth checking real-time transit or flight status before departure`];
  } else {
    travelP=`Overall travel conditions are unremarkable today.`;
    travelL=[`Check real-time traffic and transit status before longer trips`,`Watch for windshield fog from large day/night temperature swings`];
  }

  /* โ”€โ”€ 5. Weather & Car Care โ”€โ”€ */
  var carP,carL=[];
  if(t>=35){
    carP=`Extreme heat stresses your vehicle's cooling and interior components.`;
    carL=[`Check coolant level and radiator condition before long drives`,`Heat raises tire pressure โ€” verify it's within the manufacturer's spec`,`Use a sunshade to protect the dashboard and interior from UV damage`,`Never leave pets, kids, or electronics in a parked car`];
  } else if(t<=0){
    carP=`Cold weather is the leading cause of unexpected battery failure.`;
    carL=[`Have your battery tested โ€” cold cranking amps drop sharply in freezing temps`,`Keep fuel or charge above half a tank/battery to prevent line freeze or range loss`,`Verify your antifreeze/coolant mix is rated for the season's lowest temps`,`Carry an ice scraper, blanket, and basic emergency kit`];
  } else if(isSnow){
    carP=`Snow calls for extra traction and visibility precautions.`;
    carL=[`Fit winter tires or chains where required or recommended`,`Clear all snow and ice from lights, mirrors, and the roof before driving`,`Use winter-grade windshield washer fluid rated below freezing`];
  } else if(isRain||rain>=50){
    carP=`Wet roads increase hydroplaning risk โ€” check these before driving.`;
    carL=[`Verify tire tread depth is well above the legal minimum`,`Test wiper blades and replace if they're streaking`,`Confirm headlights and taillights are fully functional for low-visibility driving`];
  } else if(isStorm||wndKmh>=45){
    carP=`Storms and high wind bring debris and falling-branch risk.`;
    carL=[`Secure any roof rack cargo before setting off`,`Avoid parking under trees or near power lines`,`Increase following distance โ€” wind gusts can push vehicles off line`];
  } else if(isFog){
    carP=`Fog demands adjusted visibility habits.`;
    carL=[`Use low beams, not high beams โ€” high beams reflect off fog and reduce visibility further`,`Increase following distance substantially`];
  } else {
    carP=`Mild, clear conditions โ€” a good day for routine maintenance.`;
    carL=[`Good time for an oil check, tire rotation, or a car wash`,`Inspect tire pressure now while temperatures are stable`];
  }

  /* โ”€โ”€ 6. Weather & Health โ”€โ”€ */
  var healthP,healthL=[];
  if(uv>=8){
    healthP=`Very high UV (`+uv+`) raises sunburn and skin-damage risk.`;
    healthL=[`Apply SPF 30+ sunscreen and reapply every 2 hours outdoors`,`Wear UV-blocking sunglasses to protect your eyes`,`Seek shade during peak midday sun hours`];
  } else if(t>=35){
    healthP=`Extreme heat raises the risk of heat exhaustion and heatstroke.`;
    healthL=[`Watch for dizziness, nausea, or a rapid heartbeat โ€” signs of heat illness`,`Stay well hydrated and avoid strenuous outdoor activity`,`Check in on elderly relatives, young children, and pets, who are most vulnerable`];
  } else if(t<=0){
    healthP=`Severe cold raises the risk of hypothermia and frostbite.`;
    healthL=[`Exposed skin can suffer frostbite within minutes in severe cold`,`Dress in layers and keep extremities โ€” hands, feet, ears โ€” well covered`,`Limit continuous time outdoors and warm up periodically`];
  } else if(humid>=78){
    healthP=`High humidity can aggravate breathing for those with respiratory conditions.`;
    healthL=[`Those with asthma or allergies should monitor symptoms closely`,`Mold and dust mite activity increases indoors in humid conditions`,`Stay hydrated even though sweat evaporates more slowly`];
  } else if(humid<=30){
    healthP=`Dry air can irritate skin, eyes, and sinuses.`;
    healthL=[`Keep drinking water regularly even without feeling thirsty`,`Consider a humidifier if you have respiratory sensitivities`,`Use moisturizer and lip balm to prevent skin cracking`];
  } else if(isStorm){
    healthP=`Rapid pressure drops during storms can trigger headaches in sensitive individuals.`;
    healthL=[`Those prone to migraines or joint pain may notice symptoms before the storm arrives`,`Stay indoors and keep hydrated`];
  } else {
    healthP=`Conditions are generally favorable for outdoor activity and wellbeing.`;
    healthL=[`A good day for outdoor exercise and fresh air`,`Always consult a doctor for guidance specific to chronic conditions`];
  }

  /* โ”€โ”€ 7. Outdoor Activities โ”€โ”€ */
  var outP,outL=[];
  if(isStorm||wndKmh>=55){
    outP=`Conditions are unsafe for outdoor activity today.`;
    outL=[`Postpone hikes, sports, and outdoor plans until conditions clear`,`Stay indoors and away from windows during severe storms`,`Reschedule for a calmer day if possible`];
  } else if(isSnow){
    outP=`Snow creates great conditions for winter sports.`;
    outL=[`Skiing, snowboarding, and sledding conditions look promising`,`Check local trail or resort conditions before heading out`,`Bundle up โ€” winter sports still carry cold-exposure risk`];
  } else if(isRain||rain>=60){
    outP=`Better to shift plans indoors today.`;
    outL=[`Museums, indoor climbing gyms, malls, or a movie are good alternatives`,`If outdoor plans are unavoidable, waterproof gear is a must`,`Watch for slippery surfaces on trails and sidewalks`];
  } else if(t>=32){
    outP=`Best suited to water-based activities today.`;
    outL=[`Swimming, kayaking, or a splash pad help beat the heat`,`Shift other outdoor exercise to early morning or evening`,`Avoid strenuous activity during peak midday heat`];
  } else if(t>=15&&t<=26&&rain<30){
    outP=`Excellent all-around conditions for outdoor plans.`;
    outL=[`Great day for hiking, cycling, a picnic, or general outdoor sports`,`Comfortable conditions for a long walk or run`,`Good visibility and mild temperatures for photography or sightseeing`];
  } else if(t>=0&&t<12){
    outP=`Cool and crisp โ€” good for brisk outdoor activity.`;
    outL=[`Great for a brisk walk or run โ€” just dress in layers`,`Cycling is fine with wind-resistant outerwear`];
  } else {
    outP=`Check conditions closely before committing to outdoor plans.`;
    outL=[`Dress appropriately for the temperature extremes`,`Keep outdoor sessions shorter than usual`];
  }

  /* โ”€โ”€ 8. Severe Weather Alerts โ”€โ”€ */
  var sevList=[];
  if(isStorm) sevList.push(`&#9928; <strong>Thunderstorm</strong> โ€” lightning risk; avoid open areas and tall isolated trees.`);
  if(isSnow&&(code===75||code===86)) sevList.push(`&#10052; <strong>Heavy Snow</strong> โ€” expect reduced visibility and difficult travel conditions.`);
  if(t>=38) sevList.push(`&#127777; <strong>Extreme Heat</strong> โ€” feels like `+Math.round(feels)+`ยฐC; heat illness risk is elevated.`);
  if(t<=-10) sevList.push(`&#10052; <strong>Extreme Cold</strong> โ€” feels like `+Math.round(feels)+`ยฐC; frostbite can occur within minutes.`);
  if(Math.round(wndKmh)>=60) sevList.push(`&#128168; <strong>Damaging Winds</strong> โ€” gusts to `+Math.round(wndKmh)+`km/h; secure loose outdoor items.`);
  if(isFog) sevList.push(`&#127787; <strong>Dense Fog</strong> โ€” visibility is significantly reduced; drive with caution.`);
  if(rain>=80) sevList.push(`&#127783; <strong>Heavy Rain</strong> โ€” `+rain+`% chance; localized flooding is possible in low-lying areas.`);
  if(uv>=10) sevList.push(`&#9728; <strong>Extreme UV</strong> โ€” index `+uv+`; unprotected skin can burn in under 15 minutes.`);
  var severeCls,severeP,severeBody;
  if(sevList.length){
    severeCls=`severe`;
    severeP=`Active weather conditions worth planning around today:`;
    severeBody=`<p>`+severeP+`</p>`+wxLi(sevList);
  } else {
    severeCls=`safe`;
    severeP=`No severe weather alerts for today โ€” conditions look generally settled.`;
    severeBody=`<p>`+severeP+`</p>`;
  }

  /* โ”€โ”€ 9. Weather & Tools โ”€โ”€ */
  var dp=wxDewPoint(t,humid);
  var hi=wxHeatIndexC(t,humid);
  var wc2=wxWindChillC(t,wndKmh);
  var toolsL=[];
  toolsL.push(`<strong>Dew Point:</strong> `+Math.round(dp)+`ยฐC โ€” `+(dp>=20?`muggy, sweat evaporates slowly`:dp>=15?`somewhat humid`:dp>=10?`comfortable`:`crisp, dry air`));
  if(hi!=null) toolsL.push(`<strong>Heat Index:</strong> `+Math.round(hi)+`ยฐC โ€” how hot it actually feels with humidity factored in`);
  if(wc2!=null) toolsL.push(`<strong>Wind Chill:</strong> `+Math.round(wc2)+`ยฐC โ€” how cold exposed skin actually feels`);
  if(pressure!=null) toolsL.push(`<strong>Barometric Pressure:</strong> `+Math.round(pressure)+` hPa`);
  if(visibilityM!=null) toolsL.push(`<strong>Visibility:</strong> `+(visibilityM/1000).toFixed(1)+` km`);
  toolsL.push(`<strong>UV Safe Exposure (fair skin):</strong> `+(uv>=8?`~15โ€“20 min before burning risk`:uv>=6?`~30 min`:uv>=3?`~45 min`:`~60+ min, low risk`));

  return[
    [`cloth`,`&#128085; Weather &amp; Clothing`,`<p>`+clothP+`</p>`+wxLi(clothL)],
    [`home`,`&#127968; Weather &amp; Home`,`<p>`+homeP+`</p>`+wxLi(homeL)],
    [`garden`,`&#127793; Weather &amp; Garden`,`<p>`+gardenP+`</p>`+wxLi(gardenL)],
    [`travel`,`&#9992; Weather &amp; Travel`,`<p>`+travelP+`</p>`+wxLi(travelL)],
    [`car`,`&#128663; Weather &amp; Car Care`,`<p>`+carP+`</p>`+wxLi(carL)],
    [`health`,`&#129658; Weather &amp; Health`,`<p>`+healthP+`</p>`+wxLi(healthL)],
    [`outdoor`,`&#127939; Outdoor Activities`,`<p>`+outP+`</p>`+wxLi(outL)],
    [severeCls,`&#9888; Severe Weather Alerts`,severeBody],
    [`tools`,`&#128295; Weather &amp; Tools`,wxLi(toolsL)]
  ];
}

/* โ”€โ”€ Global Extreme Weather (persistent section, independent of search) โ”€โ”€ */
function wxLoadExtremeWeather(){
  var spots=[
    {name:`Death Valley, USA`,tag:`Hottest Place on Earth`,lat:36.5323,lon:-116.9325},
    {name:`Vostok Station, Antarctica`,tag:`Coldest Place on Earth`,lat:-78.4645,lon:106.8339},
    {name:`Mawsynram, India`,tag:`Wettest Place on Earth`,lat:25.3,lon:91.58},
    {name:`Arica, Chile`,tag:`Driest Inhabited Place`,lat:-18.4783,lon:-70.3126},
    {name:`Commonwealth Bay, Antarctica`,tag:`Windiest Place on Earth`,lat:-66.9,lon:142.6667},
    {name:`Dallol, Ethiopia`,tag:`Hottest Average Temperature`,lat:14.2417,lon:40.3}
  ];
  var lats=spots.map(function(s){return s.lat;}).join(`,`);
  var lons=spots.map(function(s){return s.lon;}).join(`,`);
  var url=`https://api.open-meteo.com/v1/forecast?latitude=`+lats+`&longitude=`+lons+`&current=temperature_2m,weather_code,wind_speed_10m&timezone=auto`;
  fetch(url).then(function(r){return r.json();}).then(function(d){
    var arr=Array.isArray(d)?d:[d];
    var html=`<div class="wx-extreme-grid">`;
    for(var i=0;i<spots.length&&i<arr.length;i++){
      var loc=spots[i],cd=arr[i];
      if(!cd||!cd.current) continue;
      var info=wxWc(cd.current.weather_code);
      html+=`<div class="wx-extreme-card">`
        +`<div class="wx-extreme-tag">`+loc.tag+`</div>`
        +`<div class="wx-extreme-name">`+loc.name+`</div>`
        +`<div class="wx-extreme-loc">Live conditions right now</div>`
        +`<div class="wx-extreme-temp">`+info.i+` `+wxToC(cd.current.temperature_2m)+`&deg;C</div>`
        +`<div class="wx-extreme-desc">`+info.d+` &middot; Wind `+wxToKmh(cd.current.wind_speed_10m)+` km/h</div>`
        +`</div>`;
    }
    html+=`</div>`;
    document.getElementById(`wxExtreme`).innerHTML=html;
  }).catch(function(){
    document.getElementById(`wxExtreme`).innerHTML=`<p class="wx-nearby-loading">Global extreme weather data is temporarily unavailable.</p>`;
  });
}

document.getElementById(`wxCityInput`).addEventListener(`keypress`,function(e){
  if(e.key===`Enter`) wxSearchCity();
});
window.onload=function(){
  wxDetectLocation();
  wxLoadExtremeWeather();
};
</script>
</body>
</html>

Scroll to Top