<!-- CREATOR - S GIBBS -->
<!-- MCARS -  MAPPING CONTROL & AWARENESS RESPONSE-->
<!-- PLANETARY OVERVIEW -->
<!-- 12/01/2026, STABLE VERSION V3 →
<!-- API KEYS NEEDED, SEE BELOW -->

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>COMMAND INTERFACE</title>

<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
}

<style>
html, body {
  margin:0;
  height:100%;
  background:#000;
  font-family:Impact;
  overflow:hidden;
}

/* ================= MAP ================= */
#map {
  position:absolute;
  top:6vh;
  bottom:6vh;
  left:18vw;
  right:4vw;
  z-index:1;
}

/* ================= FRAME ================= */
#frame {
  position:absolute;
  inset:0;
  pointer-events:none;
  z-index:1000;
  border-top:3vh solid #777;
  border-left:2vw solid #777;
  border-bottom:2vh solid #777;
  border-top-left-radius:8vw;
  border-bottom-left-radius:8vw;
}
#frame::after {
  content:"";
  position:absolute;
  inset:0;
  margin:2vh;
  border-top:0.8vh solid #444;
  border-left:0.8vw solid #444;
  border-bottom:0.8vh solid #444;
  border-top-left-radius:6vw;
  border-bottom-left-radius:6vw;
}

/* ================= ACCENTS ================= */
#accent-top, #accent-bottom {
  position:absolute;
  background:#ff7f27;
  z-index:1001;
}

#accent-top {
  right:22vw;
  top:0;
  width:30vw;
  height:4vh;
}

#accent-bottom {
  right:22vw;
  bottom:0;
  width:30vw;
  height:3vh;
}

#accent-top::before, #accent-top::after,
#accent-bottom::before, #accent-bottom::after {
  content:"";
  position:absolute;
  width:0.3vw;
  height:100%;
  background:black;
}
#accent-top::before, #accent-bottom::before { left:-0.3vw; }
#accent-top::after, #accent-bottom::after { right:-0.3vw; }

/* ================= LEFT RAILS ================= */
#accent-left {
  position:absolute;
  left:0;
  top:15vh;
  width:2vw;
  height:22vh;
  background:#313649;
  z-index:1001;
}

#accent-left2 {
  position:absolute;
  left:0;
  top:45vh;
  width:2vw;
  height:35vh;
  background:#ff7f27;
  z-index:1001;
}

#accent-left::before,
#accent-left::after,
#accent-left2::before,
#accent-left2::after {
  content:"";
  position:absolute;
  left:0;
  width:100%;
  height:0.4vh;
  background:#000;
}
#accent-left::before,
#accent-left2::before { top:0; }
#accent-left::after,
#accent-left2::after { bottom:0; }

/* ================= TITLE ================= */
#title {
  position:absolute;
  top:0;
  left:8vw;
  height:4.2vh;
  display:flex;
  align-items:center;
  padding:0 1vw;
  background:black;
  color:#5cb8e1;
  font-size:2.9vh;
  z-index:1002;
}

/* ================= PANEL (FIXED RESPONSIVE) ================= */
#panel {
  position:absolute;
  top:10vh;
  left:6vw;
  width:13vw;
  min-width:160px;
  max-width:240px;
  z-index:1002;
  color:white;
  font-size:1.7vh;
}

.btn {
  width:80%;
  padding:1.6vh;
  margin:0.5vh 0.1vh;
  border:none;
  background:#5cb8e1;
  color:black;
  cursor:pointer;
  font-size:1.9vh;
  font-family:Impact;
border-radius: 999px;

}

@keyframes flash {
  0%   { background:#5cb8e1; }
  50%  { background:#ff7f27; }
  100% { background:#5cb8e1; }
}
.btn:nth-child(3) { animation: flash 3.9s infinite; }  /* EARTH */
.btn:nth-child(4) { animation: flash 2.8s infinite; }  /* ASTEROIDS */
.btn:nth-child(6) { animation: flash 4.5s infinite; }  /* ISS */
.btn:nth-child(9) { animation: flash 3.6s infinite; }  /* LIGHT/DARK */

.flash {
  animation: flash 1s infinite;
}

.btn:hover {
  background:#4fc3f7;
  color:#000;
}

#weatherDetails {
  font-size:1.9vh;
  margin-top:1vh;
  white-space:pre-line;
}

</style>
</head>

<body>

<div id="frame"></div>
<div id="accent-top"></div>
<div id="accent-bottom"></div>
<div id="accent-left"></div>
<div id="accent-left2"></div>

<div id="title">LCARS: PLANETARY OVERVIEW</div>

<div id="panel">
  <div>THREAT:</div>
  <div id="threatText">NORMAL</div>

  <button class="btn" onclick="playClick(); loadEarthquakes()">EARTHQUAKES</button>
  <button class="btn" onclick="playClick(); loadAsteroids()">ASTEROIDS</button>
  <button class="btn" onclick="playClick(); loadSolar()">SOLAR</button>
  <button class="btn" onclick="playClick(); updateISS()">ISS</button>
  <button class="btn" onclick="playClick(); loadWeather()">WEATHER</button>
  <button class="btn" onclick="playClick(); loadPower()">POWER</button>
  <button class="btn" onclick="playClick(); toggleTheme()">LIGHT/DARK</button>

  <div id="weatherDetails"></div>
</div>

<div id="map"></div>

<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>

<script>
const NASA_KEY = "INSERT YOU NASA API KEY HERE";
const WEATHER_KEY = "INSERT YOUR WEATHER API KEY HERE";
const ELECTRICITY_KEY = "INSERT YOUR ELECTRIC GRID API KEY HERE";

function playClick(){
  clickSound.currentTime = 0; // allows rapid re-clicks
  clickSound.play();
}

const clickSound = new Audio("keyok3.mp3");

const map = L.map('map').setView([20,0],2);

let darkLayer = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png').addTo(map);
let lightLayer = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png');

let markers = [];
let issMarker;
let isLight = false;
let active = null;

let issPath = [];
let issLine;

const icon = (emoji,size=20)=>L.divIcon({
  html:`<div style="font-size:${size}px">${emoji}</div>`,
  className:''
});

function clearAll(){
  markers.forEach(m=>map.removeLayer(m));
  markers=[];
}

function toggleTheme(){

  // remove both layers first (safe reset)
  map.removeLayer(darkLayer);
  map.removeLayer(lightLayer);

  if(isLight){
    darkLayer.addTo(map);
  } else {
    lightLayer.addTo(map);
  }

  isLight = !isLight;
}

function toggle(name){
  if(active===name){
    clearAll();
    active=null;
    return false;
  }
  clearAll();
  active=name;
  return true;
}

/* EARTHQUAKES */
async function loadEarthquakes(){
  if(!toggle("earth")) return;

  const res = await fetch("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson");
  const data = await res.json();

  data.features.forEach(eq=>{
    const [lon,lat]=eq.geometry.coordinates;

    const m = L.marker([lat,lon],{icon:icon("🌍")})
      .addTo(map)
      .bindPopup(`
        🌍 <b>Earthquake</b><br>
        Mag: ${eq.properties.mag}<br>
        Location: ${eq.properties.place}<br>
        Time: ${new Date(eq.properties.time).toLocaleString()}
      `);

    markers.push(m);
  });
}

/* ASTEROIDS */
async function loadAsteroids(){
  if(!toggle("asteroids")) return;

  const today=new Date().toISOString().split('T')[0];
  const res=await fetch(`https://api.nasa.gov/neo/rest/v1/feed?start_date=${today}&api_key=${NASA_KEY}`);
  const data=await res.json();

  (data.near_earth_objects[today]||[]).forEach(a=>{
    const lat=(Math.random()*140)-70;
    const lon=(Math.random()*360)-180;

    const m = L.marker([lat,lon],{icon:icon("☄️")})
      .addTo(map)
      .bindPopup(`
        ☄️ <b>${a.name}</b><br>
        Hazardous: ${a.is_potentially_hazardous_asteroid}<br>
        Estimated diameter: ${a.estimated_diameter.meters.estimated_diameter_max.toFixed(0)} m
      `);

    markers.push(m);
  });
}

/* SOLAR */
async function loadSolar(){
  if(!toggle("solar")) return;

  const res=await fetch(`https://api.nasa.gov/DONKI/FLR?api_key=${NASA_KEY}`);
  const data=await res.json();

  data.slice(-5).forEach(f=>{
    const lat=(Math.random()*140)-70;
    const lon=(Math.random()*360)-180;

    const m = L.marker([lat,lon],{icon:icon("☀️")})
      .addTo(map)
      .bindPopup(`☀️ Solar Flare<br>Class: ${f.classType}`);

    markers.push(m);
  });
}

/* WEATHER */
async function loadWeather(){
  if(!toggle("weather")) return;

  const cities=[
    {n:"London",lat:51.5,lon:-0.1},
    {n:"New York",lat:40.7,lon:-74},
    {n:"Tokyo",lat:35.6,lon:139.7},
    {n:"Paris",lat:48.85,lon:2.35},
    {n:"Sydney",lat:-33.86,lon:151.21},
    {n:"Dubai",lat:25.20,lon:55.27},
    {n:"Berlin",lat:52.52,lon:13.40},
    {n:"Los Angeles",lat:34.05,lon:-118.24},
    {n:"Singapore",lat:1.35,lon:103.82},
    {n:"Cape Town",lat:-33.92,lon:18.42},
    {n:"Rio de Janeiro",lat:-22.91,lon:-43.17},
    {n:"Toronto",lat:43.65,lon:-79.38},
    {n:"Moscow",lat:55.75,lon:37.62}
  ];

  let out="";

  for(let c of cities){
    const res=await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${c.lat}&lon=${c.lon}&appid=${WEATHER_KEY}`);
    const d=await res.json();

    const temp=(d.main.temp-273.15).toFixed(1);

    const m = L.marker([c.lat,c.lon],{icon:icon("🌦️")})
      .addTo(map)
      .bindPopup(`
        🌦️ <b>${c.n}</b><br>
        Temp: ${temp}°C<br>
        Condition: ${d.weather[0].main}<br>
        Humidity: ${d.main.humidity}%<br>
        Wind: ${d.wind.speed} m/s
      `);

    markers.push(m);
    out+=`${c.n}: ${temp}°C<br>`;
  }

  document.getElementById('weatherDetails').innerHTML=out;
}

async function loadPower(){
  if(!toggle("power")) return;

  markers = [];

  const regions = [
    {name:"UK", zone:"GB", lat:54, lon:-2},
    {name:"France", zone:"FR", lat:46, lon:2},
    {name:"Germany", zone:"DE", lat:51, lon:10},
    {name:"Spain", zone:"ES", lat:40, lon:-3},
    {name:"Italy", zone:"IT", lat:42, lon:12},
    {name:"US West", zone:"US-CAL-CISO", lat:36, lon:-119},
    {name:"US East", zone:"US-CAR-CAR", lat:40, lon:-75},
    {name:"India", zone:"IN", lat:22, lon:78},
    {name:"Japan", zone:"JP", lat:36, lon:138}
  ];

  for(let r of regions){

    try {
      const d = await getCarbon(r.zone);

      const carbon = d.carbonIntensity;
      const renewable = d.renewablePercentage || 0;

      // ===== THREAT ENGINE =====
      let status = "CLEAN";
      let iconColor = "🟢";

      if(carbon > 450){
        status = "GRID STRESS";
        iconColor = "🔴";
        document.getElementById("threatText").innerText = "🔴 GRID STRESS";
        document.getElementById("accent-left2").style.background = "#ff0000";
      }
      else if(carbon > 250){
        status = "HIGH LOAD";
        iconColor = "⚠️";
        document.getElementById("threatText").innerText = "⚠️ HIGH LOAD";
        document.getElementById("accent-left2").style.background = "#ff7f27";
      }
      else {
        document.getElementById("threatText").innerText = "🟢 CLEAN ENERGY";
        document.getElementById("accent-left2").style.background = "#00ff88";
      }

      const m = L.marker([r.lat, r.lon], {
        icon: icon(iconColor, 22)
      }).addTo(map);

      m.bindPopup(`
        ⚡ <b>${r.name}</b><br><br>

        🌍 Carbon: ${carbon} gCO₂/kWh<br>
        🌱 Renewable: ${renewable}%<br>
        🔥 Status: ${status}<br>
        📡 Zone: ${r.zone}
      `);

      markers.push(m);

    } catch(err){
      console.log("Power data failed for", r.name);
    }
  }
}
async function getCarbon(zone, datetime = null){

  let url = `https://api.electricitymaps.com/v3/carbon-intensity/latest?zone=${zone}`;

  if(datetime){
    url = `https://api.electricitymaps.com/v3/carbon-intensity/past?zone=${zone}&datetime=${datetime}`;
  }

  const res = await fetch(url, {
    headers: {
      "auth-token": ELECTRICITY_KEY
    }
  });

  return await res.json();
}

/* ISS */
async function updateISS(){
  const res = await fetch("https://api.wheretheiss.at/v1/satellites/25544");
  const d = await res.json();

  const latlng = [d.latitude, d.longitude];

  // ===== MARKER =====
  if(!issMarker){
    issMarker = L.marker(latlng,{icon:icon("🛰️",30)}).addTo(map);
  } else {
    issMarker.setLatLng(latlng);
  }

  // ===== TRAIL TRACKING =====
  issPath.push(latlng);

  // limit trail length (important)
  if(issPath.length > 50){
    issPath.shift();
  }

  // ===== DRAW / UPDATE LINE =====
  if(!issLine){
    issLine = L.polyline(issPath, {
      color: '#00ffff',
      weight: 2,
      opacity: 0.7
    }).addTo(map);
  } else {
    issLine.setLatLngs(issPath);
  }

  // ===== POPUP (keep yours as-is) =====
  const speedKmh = d.velocity.toFixed(0);
  const altitude = d.altitude.toFixed(0);

  issMarker.bindPopup(`
    🛰️ <b>International Space Station</b><br><br>
    🌍 Lat: ${d.latitude.toFixed(2)}<br>
    🌍 Lon: ${d.longitude.toFixed(2)}<br><br>
    🚀 Speed: ${speedKmh} km/h<br>
    📏 Altitude: ${altitude} km
  `);
}

updateISS();                  // run once immediately
setInterval(updateISS, 2000); // update every 2 seconds

</script>

<button onclick="window.close()" style="
position:fixed;
top:0px;
right:0px;
width:130px;
height:30px;
z-index:9999;
padding:3px;
background:#000000;
color:#00bbff;
border:none;
font-family:Impact;
font-size:18px;">

EXIT SYSTEM
</button>

</body>
</html>