<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>RideX — On-demand rides (Demo)</title>
<meta name="description" content="RideX — Book reliable rides in minutes. Customer and Driver dashboards. Demo with localStorage persistence."/>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;800&display=swap" rel="stylesheet">
<style>
  :root{
    --bg:#0b1220; --card:#071029; --muted:#9aa7d6; --accent:#07a0ff; --accent-2:#6ddcff; --glass:rgba(255,255,255,0.04);
    --radius:14px; --maxw:1200px;
  }
  *{box-sizing:border-box}
  body{margin:0;font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial;background:linear-gradient(180deg,#071028 0%, #08172d 40%, #071028 100%);color:#e7f0ff;min-height:100vh}
  a{color:inherit;text-decoration:none}
  .container{max-width:var(--maxw);margin:0 auto;padding:28px}
  header{display:flex;align-items:center;justify-content:space-between;gap:16px}
  .brand{display:flex;gap:12px;align-items:center}
  .logo{width:56px;height:56px;border-radius:12px;background:linear-gradient(135deg,var(--accent),var(--accent-2));display:grid;place-items:center;font-weight:800;color:#041027}
  .nav{display:flex;gap:10px;align-items:center}
  .nav button{background:transparent;border:1px solid rgba(255,255,255,0.06);padding:8px 12px;border-radius:999px;color:var(--muted);cursor:pointer}
  .hero{display:grid;grid-template-columns:1fr 520px;gap:28px;align-items:center;margin-top:28px}
  .hero-left h1{font-size:36px;margin:0 0 10px 0;line-height:1.02}
  .tag{color:var(--muted);margin-bottom:18px}
  .cta-row{display:flex;gap:12px;flex-wrap:wrap}
  .btn{background:linear-gradient(90deg,var(--accent),var(--accent-2));color:#041027;border:none;padding:12px 18px;border-radius:12px;font-weight:700;cursor:pointer;box-shadow:0 10px 30px rgba(7,160,255,0.12)}
  .btn.ghost{background:transparent;border:1px solid rgba(255,255,255,0.06);color:var(--muted);box-shadow:none}
  .hero-right .card{background:linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); border-radius:16px;padding:14px;border:1px solid rgba(255,255,255,0.03)}
  .search{display:flex;gap:8px;align-items:center}
  .search input, .search select{background:transparent;border:1px solid rgba(255,255,255,0.06);padding:10px;border-radius:10px;color:var(--muted);min-width:0}
  .search input::placeholder{color:rgba(231,240,255,0.38)}
  .small{font-size:13px;color:var(--muted)}
  .grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:28px}
  .feature{background:var(--card);border-radius:12px;padding:16px;border:1px solid rgba(255,255,255,0.03)}
  footer{margin-top:40px;padding-top:22px;border-top:1px solid rgba(255,255,255,0.02);display:flex;justify-content:space-between;align-items:center;color:var(--muted)}
  /* Map */
  #map{height:420px;border-radius:12px;border:1px solid rgba(255,255,255,0.03);overflow:hidden}
  /* Modals */
  .modal-back{position:fixed;inset:0;background:rgba(0,0,0,0.6);display:none;align-items:center;justify-content:center;z-index:40}
  .modal{background:linear-gradient(180deg,#0b1220,#071028);padding:20px;border-radius:12px;width:420px;border:1px solid rgba(255,255,255,0.04);box-shadow:0 50px 120px rgba(0,0,0,0.6)}
  .field{display:flex;flex-direction:column;margin-bottom:10px}
  .field label{font-size:13px;color:var(--muted);margin-bottom:6px}
  .field input{padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,0.04);background:transparent;color:#e7f0ff}
  .row{display:flex;gap:8px}
  .muted{color:var(--muted)}
  /* responsive */
  @media(max-width:1024px){ .hero{grid-template-columns:1fr} #map{height:300px} .hero-right{order:2} }
</style>
</head>
<body>
  <div class="container">
    <header>
      <div class="brand">
        <div class="logo">RX</div>
        <div>
          <div style="font-weight:700">RIDEX</div>
          <div class="small">Safe • Fast • Local</div>
        </div>
      </div>

      <nav class="nav" aria-label="Main">
        <button class="nav-btn ghost" id="navHome">Home</button>
        <button class="nav-btn ghost" id="navHow">How it works</button>
        <button class="nav-btn ghost" id="btnOpenLogin">Sign in</button>
      </nav>
    </header>

    <main class="hero" role="main">
      <div class="hero-left">
        <h1>Book a ride in minutes</h1>
        <div class="tag">Quick pickups, reliable drivers, transparent fares. Serving cities across India.</div>

        <div class="cta-row">
          <button class="btn" id="btnCustomer">Book a ride</button>
          <button class="btn ghost" id="btnDriver">Driver sign in</button>
          <button class="btn ghost" id="btnSupport">Customer care</button>
        </div>

        <div class="small" style="margin-top:18px">Contact: +91 9985808902 • info.ghinnovationssolutions@gmail.com</div>

        <div class="grid-3" style="margin-top:24px">
          <div class="feature">
            <div style="font-weight:700">Transparent fares</div>
            <div class="muted">Know your fare before you ride — no surprises.</div>
          </div>
          <div class="feature">
            <div style="font-weight:700">Trusted drivers</div>
            <div class="muted">Background-checked drivers and verified vehicles.</div>
          </div>
          <div class="feature">
            <div style="font-weight:700">24/7 support</div>
            <div class="muted">Help available any time you need it.</div>
          </div>
        </div>
      </div>

      <!-- Booking card with small map (right) -->
      <div class="hero-right">
        <div class="card">
          <div style="display:flex;justify-content:space-between;align-items:center">
            <div style="font-weight:700">Quick Book</div>
            <div class="small">Currency: ₹ (INR)</div>
          </div>

          <div style="margin-top:12px" class="search">
            <div style="flex:1">
              <input id="pickup" placeholder="Pickup (type or click map)" aria-label="Pickup"/>
            </div>
            <div style="flex:1">
              <input id="drop" placeholder="Drop (type or click map)" aria-label="Drop"/>
            </div>
          </div>

          <div style="display:flex;gap:8px;margin-top:10px;align-items:center">
            <select id="rideType" style="padding:10px;border-radius:10px;border:1px solid rgba(255,255,255,0.04);background:transparent;color:var(--muted)">
              <option value="mini">Mini</option><option value="sedan">Sedan</option><option value="suv">SUV</option>
            </select>
            <button class="btn" id="getQuote">Get fare</button>
            <div style="flex:1"></div>
            <button class="btn ghost" id="bookRide">Book</button>
          </div>

          <div style="margin-top:12px;display:flex;gap:8px;align-items:center">
            <div class="small">Est dist:</div><div id="estKm" style="font-weight:800">—</div>
            <div style="flex:1"></div>
            <div class="small">Fare:</div><div id="estFare" style="font-weight:800">₹0.00</div>
          </div>
        </div>

        <div style="margin-top:14px">
          <div id="map"></div>
        </div>
      </div>
    </main>

    <section id="how" style="margin-top:28px">
      <div style="display:flex;justify-content:space-between;gap:16px;align-items:flex-start">
        <div style="flex:1" class="card">
          <h3 style="margin-top:0">How it works</h3>
          <ol class="muted">
            <li>Enter pickup &amp; drop, get an instant fare.</li>
            <li>Confirm booking — nearby driver accepts.</li>
            <li>Live map shows driver ETA and route.</li>
          </ol>
        </div>
        <div style="width:320px" class="card">
          <h4 style="margin:0">Need help?</h4>
          <div class="muted" style="margin-top:8px">Call: +91 9985808902<br/>Email: info.ghinnovationssolutions@gmail.com</div>
        </div>
      </div>
    </section>

    <footer>
      <div class="small">© 2025 RideX (demo) — Built for GH Innovations</div>
      <div class="small">Made with ♥ in India</div>
    </footer>
  </div>

  <!-- Modals -->
  <div class="modal-back" id="modalBack">
    <div class="modal" id="modalContent" role="dialog" aria-modal="true">
      <!-- dynamic content injected -->
    </div>
  </div>

<!-- ====== SCRIPTS ====== -->
<script>
/*
  Demo app behavior:
  - Stores users in localStorage.key 'rx_users' (array of {name,email,password})
  - Stores drivers in 'rx_drivers'
  - Stores rides in 'rx_rides'
  - Google Maps (replace YOUR_GOOGLE_MAPS_API_KEY in script tag below)
*/

const INR = new Intl.NumberFormat('en-IN',{style:'currency',currency:'INR'});
const $ = sel => document.querySelector(sel);
const $$ = sel => Array.from(document.querySelectorAll(sel));
const modalBack = document.getElementById('modalBack');
const modalContent = document.getElementById('modalContent');

function read(key){ try{ return JSON.parse(localStorage.getItem(key))||[] }catch(e){ return [] } }
function write(key, v){ localStorage.setItem(key, JSON.stringify(v)) }

// open modal helper
function openModal(html){ modalContent.innerHTML = html; modalBack.style.display='flex'; }
function closeModal(){ modalBack.style.display='none'; modalContent.innerHTML=''; }

// show login/register flows
document.getElementById('btnOpenLogin')?.addEventListener('click', ()=> showLogin());
document.getElementById('btnCustomer').addEventListener('click', ()=> showLogin());
document.getElementById('btnDriver').addEventListener('click', ()=> showDriverOtp());
document.getElementById('btnSupport').addEventListener('click', ()=> alert('Contact: +91 9985808902\\ninfo.ghinnovationssolutions@gmail.com'));

// login modal
function showLogin(){
  openModal(`
    <h3 style="margin-top:0">Customer Login</h3>
    <div class="field"><label>Email</label><input id="m_email" type="email"></div>
    <div class="field"><label>Password</label><input id="m_pass" type="password"></div>
    <div style="display:flex;gap:8px;justify-content:flex-end">
      <button class="btn ghost" id="m_forgot">Forgot</button>
      <button class="btn" id="m_login">Sign in</button>
    </div>
    <div style="margin-top:12px" class="small">New to RideX? <a href="#" id="m_register_link">Create account</a></div>
  `);
  document.getElementById('m_login').onclick = doLogin;
  document.getElementById('m_forgot').onclick = doForgot;
  document.getElementById('m_register_link').onclick = (e)=>{ e.preventDefault(); showRegister(); };
}

function showRegister(){
  openModal(`
    <h3 style="margin-top:0">Create account</h3>
    <div class="field"><label>Full name</label><input id="r_name"></div>
    <div class="field"><label>Email</label><input id="r_email" type="email"></div>
    <div class="field"><label>Password</label><input id="r_pass" type="password"></div>
    <div style="display:flex;gap:8px;justify-content:flex-end">
      <button class="btn ghost" id="r_cancel">Cancel</button>
      <button class="btn" id="r_signup">Create</button>
    </div>
  `);
  document.getElementById('r_cancel').onclick = closeModal;
  document.getElementById('r_signup').onclick = doRegister;
}

function doRegister(){
  const name = modalContent.querySelector('#r_name').value.trim();
  const email = modalContent.querySelector('#r_email').value.trim().toLowerCase();
  const pass = modalContent.querySelector('#r_pass').value;
  if(!name||!email||!pass){ alert('Complete all fields'); return; }
  let users = read('rx_users');
  if(users.find(u=>u.email===email)){ alert('Email already registered'); return; }
  users.push({id:'u_'+Math.random().toString(36).slice(2,8),name,email,password:pass});
  write('rx_users', users);
  alert('Account created — you can now sign in');
  closeModal();
  showLogin();
}

function doLogin(){
  const email = modalContent.querySelector('#m_email').value.trim().toLowerCase();
  const pass = modalContent.querySelector('#m_pass').value;
  let users = read('rx_users');
  const u = users.find(x=>x.email===email);
  if(!u){ if(confirm('No account found. Register?')){ closeModal(); showRegister(); } else return; }
  if(u.password !== pass){ if(confirm('Wrong password. Reset?')){ doForgot(); } else return; }
  // login success: persist current user id
  localStorage.setItem('rx_current', JSON.stringify(u));
  closeModal();
  alert('Signed in — welcome ' + u.name);
  // show user name in header
  updateUserUI();
}

function doForgot(){
  const email = modalContent.querySelector('#m_email')?.value?.trim()?.toLowerCase() || prompt('Enter your email to receive reset instructions');
  if(!email) return;
  let users = read('rx_users');
  const u = users.find(x=>x.email===email);
  if(!u) return alert('No account for this email');
  // demo: show password (unsafe in real app). In production send reset email.
  alert('Demo reset — your password is: ' + u.password);
}

// driver OTP modal
function showDriverOtp(){
  openModal(`
    <h3 style="margin-top:0">Driver login (OTP)</h3>
    <div class="field"><label>Mobile</label><input id="drv_phone" placeholder="+91..."></div>
    <div style="display:flex;gap:8px;justify-content:flex-end">
      <button class="btn ghost" id="drv_send">Send OTP</button>
    </div>
  `);
  document.getElementById('drv_send').onclick = ()=> {
    const phone = modalContent.querySelector('#drv_phone').value.trim();
    if(!phone){ alert('Enter phone'); return; }
    const otp = Math.floor(1000 + Math.random()*9000).toString();
    localStorage.setItem('rx_driver_otp', otp);
    // In production send via SMS (Twilio/Firebase). Here show in alert for demo.
    alert('OTP (demo): ' + otp);
    // show OTP entry
    modalContent.innerHTML += `<div class="field" style="margin-top:10px"><label>Enter OTP</label><input id="drv_otp" /></div>
      <div style="display:flex;gap:8px;justify-content:flex-end"><button class="btn" id="drv_verify">Verify</button></div>`;
    document.getElementById('drv_verify').onclick = verifyDriverOtp;
  };
}

function verifyDriverOtp(){
  const entered = modalContent.querySelector('#drv_otp').value.trim();
  const otp = localStorage.getItem('rx_driver_otp');
  if(entered === otp){
    // mark driver logged in
    const driver = {id:'d_'+Math.random().toString(36).slice(2,8),phone: modalContent.querySelector('#drv_phone').value};
    let drivers = read('rx_drivers'); drivers.push(driver); write('rx_drivers', drivers);
    localStorage.setItem('rx_current_driver', JSON.stringify(driver));
    alert('Driver logged in (demo)');
    closeModal();
    updateUserUI();
    // show driver controls (simulate)
    openDriverPanel();
  } else { alert('Invalid OTP'); }
}

// update user UI
function updateUserUI(){
  const cur = JSON.parse(localStorage.getItem('rx_current') || 'null');
  const curDrv = JSON.parse(localStorage.getItem('rx_current_driver') || 'null');
  if(cur) {
    document.querySelector('.small') && (document.querySelector('.small').textContent = 'Hi, ' + cur.name);
    document.querySelector('#btnOpenLogin') && (document.querySelector('#btnOpenLogin').textContent = 'Account');
  } else if(curDrv){
    document.querySelector('.small') && (document.querySelector('.small').textContent = 'Driver • ' + curDrv.phone);
    document.querySelector('#btnOpenLogin') && (document.querySelector('#btnOpenLogin').textContent = 'Account');
  }
}
updateUserUI();

// ===== Google Maps setup =====
let map, directionsService, directionsRenderer, pickupMarker, dropMarker, pickupPos, dropPos;
function initMap(){
  // default center (Visakhapatnam)
  const center = {lat:17.6868, lng:83.2185};
  map = new google.maps.Map(document.getElementById('map'), { center, zoom:12, disableDefaultUI:false });
  directionsService = new google.maps.DirectionsService();
  directionsRenderer = new google.maps.DirectionsRenderer({ map });
  pickupMarker = new google.maps.Marker({ map, label: 'P' });
  dropMarker = new google.maps.Marker({ map, label: 'D' });

  // Places autocomplete
  const acPickup = new google.maps.places.Autocomplete(document.getElementById('pickup'));
  const acDrop = new google.maps.places.Autocomplete(document.getElementById('drop'));
  acPickup.bindTo('bounds', map); acDrop.bindTo('bounds', map);
  acPickup.addListener('place_changed', ()=> {
    const p = acPickup.getPlace(); if(p.geometry) setPickup({ lat: p.geometry.location.lat(), lng: p.geometry.location.lng(), text: p.formatted_address || p.name });
  });
  acDrop.addListener('place_changed', ()=> {
    const p = acDrop.getPlace(); if(p.geometry) setDrop({ lat: p.geometry.location.lat(), lng: p.geometry.location.lng(), text: p.formatted_address || p.name });
  });

  // click map to toggle pickup / drop
  let placing = 'pickup';
  map.addListener('click', (ev)=> {
    const pos = { lat: ev.latLng.lat(), lng: ev.latLng.lng(), text: 'Pinned location' };
    if(placing === 'pickup'){ setPickup(pos); document.getElementById('pickup').value = pos.text; placing = 'drop'; }
    else { setDrop(pos); document.getElementById('drop').value = pos.text; placing = 'pickup'; }
  });
}

// set positions
function setPickup(p){ pickupPos = p; pickupMarker.setPosition(p); map.panTo(p); }
function setDrop(p){ dropPos = p; dropMarker.setPosition(p); map.panTo(p); }

// Calculate route & fare
document.getElementById('getQuote').addEventListener('click', ()=> {
  if(!pickupPos || !dropPos){
    // try geocode from text if markers not set
    const a = document.getElementById('pickup').value, b = document.getElementById('drop').value;
    if(!a||!b){ alert('Set pickup and drop (type or click map)'); return; }
  }
  if(!pickupPos || !dropPos){
    // try geocode quickly via placesService text search (use basic directionsService that accepts strings)
    directionsService.route({ origin: document.getElementById('pickup').value, destination: document.getElementById('drop').value, travelMode: 'DRIVING' }, (res, status) => {
      if(status==='OK'){ handleRouteResult(res); } else alert('Route error: '+status);
    });
  } else {
    directionsService.route({ origin: pickupPos, destination: dropPos, travelMode: 'DRIVING' }, (res, status) => {
      if(status==='OK'){ handleRouteResult(res); } else alert('Route error: '+status);
    });
  }
});

function handleRouteResult(res){
  directionsRenderer.setDirections(res);
  const leg = res.routes[0].legs[0];
  const km = Number(leg.distance.value/1000).toFixed(1);
  document.getElementById('estKm').textContent = km + ' km';
  const fare = estimateFare(document.getElementById('rideType').value, km);
  document.getElementById('estFare').textContent = INR.format(fare);
}

// simple fare model
function estimateFare(type, km){
  const base = { mini:40, sedan:60, suv:80 };
  const per  = { mini:12, sedan:15, suv:18 };
  km = Number(km) || 1;
  return Math.round((base[type] + per[type]*km)*100)/100;
}

// Book ride (persist ride and simulate driver notification)
document.getElementById('bookRide').addEventListener('click', ()=> {
  const cur = JSON.parse(localStorage.getItem('rx_current')||'null');
  if(!cur){ if(!confirm('You are not signed in. Continue as guest?')) return; }
  // save ride
  const ride = {
    id: 'r_'+Math.random().toString(36).slice(2,8),
    user: cur ? cur.name : 'Guest',
    pickup: document.getElementById('pickup').value,
    drop: document.getElementById('drop').value,
    rideType: document.getElementById('rideType').value,
    fare: document.getElementById('estFare').textContent,
    created: new Date().toISOString(),
    status: 'requested'
  };
  let rides = read('rx_rides'); rides.push(ride); write('rx_rides', rides);
  alert('Ride requested — searching for drivers (demo).');
  // simulate notify drivers
  simulateDriverNotification(ride);
});

// Simulate driver notification (mock of real-time push)
// If there's a logged-in driver (rx_current_driver) notify them in this same browser client.
// In production, push via WebSocket / FCM.
function simulateDriverNotification(ride){
  // play alarm for driver
  const drv = JSON.parse(localStorage.getItem('rx_current_driver')||'null');
  if(!drv){
    console.log('No driver online (demo). Ride in queue.');
    return;
  }
  // show tiny accept dialog for demo
  if(confirm('Driver ' + drv.phone + ' — accept incoming ride? (demo)')){
    // accept -> show driver route
    const accepted = JSON.parse(localStorage.getItem('rx_rides'))?.find(r=>r.id===ride.id);
    accepted.status = 'accepted';
    write('rx_rides', read('rx_rides')); // update
    alert('Ride accepted — navigate to pickup (demo).');
    // optionally render route on map for driver
    directionsService.route({ origin: ride.pickup, destination: ride.drop, travelMode: 'DRIVING' }, (res, status) => {
      if(status==='OK'){ directionsRenderer.setDirections(res); }
    });
  } else {
    alert('Driver declined (demo).');
  }
}

// driver panel (for demo)
function openDriverPanel(){
  // For this demo we simply show an alert and update header
  alert('Driver panel opened (demo). You will receive ride popups here.');
}

// close modal on background click
modalBack.addEventListener('click', (e)=> { if(e.target === modalBack) closeModal(); });

// start map script loader
function loadGoogleMaps(){
  // script tag added in DOM end; function initMap will be invoked by callback
}
// run UI updates
updateUserUI();
</script>

<!-- Google Maps JS: replace key with your API KEY; include places library and callback to initMap -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY&libraries=places&callback=initMap" async defer></script>
</body>
</html>