����JFIF��`�`�����Viewing File: /home/u820193700/domains/thereown.com/public_html/temp_script.js
��

> <script>

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � DATA �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  /* hue = actual RE paint colour of that variant (approx), hue2 = accent/pinstripe */

  const BIKES=[

   {id:1,acc:["Engine guard","Touring seat","Tank pad"],km:"9,842 km",owner:"1st Owner",insValid:"Mar 

2027",shortlisted:9,year:2021,arrived:"2026-07-07",name:"Classic 350",variant:"Halcyon 

Green",div:"Bengaluru",reg:"KA05LF1457",cc:350,asking:128000,market:155000,newPrice:240000,newRef:"Classic 

350",hue:"#2E5C43",hue2:"#C9A84C",type:"Cruiser",power:"20.2 bhp"},

   {id:2,acc:["Sump guard","Handlebar brace","Fog lamps"],km:"7,210 km",owner:"1st Owner",insValid:"Jul 

2027",shortlisted:7,year:2022,arrived:"2026-07-06",name:"Scram 411",variant:"Graphite 

Yellow",div:"Bengaluru",reg:"KA05LJ4716",cc:411,asking:118000,market:145000,newPrice:270000,newRef:"Scram 

440",hue:"#E8B400",hue2:"#2b2b2e",type:"Scrambler",power:"24.3 bhp"},

   {id:3,acc:["Panniers + stays","Windscreen","Engine guard"],km:"11,480 km",owner:"1st Owner",insValid:"Jan 

2027",shortlisted:5,year:2022,arrived:"2026-07-04",name:"Himalayan",variant:"Granite 

Black",div:"Bengaluru",reg:"KA05LN0602",cc:411,asking:155000,market:190000,newPrice:390000,newRef:"Himalayan 

450",hue:"#26262a",hue2:"#7a7a80",type:"Adventure",power:"24.3 bhp"},

   {id:4,acc:["Crash guard","Bar-end mirrors"],km:"6,950 km",owner:"1st Owner",insValid:"Sep 

2027",shortlisted:3,year:2022,arrived:"2026-06-28",name:"Hunter 350",variant:"Rebel 

Black",div:"Bengaluru",reg:"KA05LM6876",cc:350,asking:118000,market:145000,newPrice:177000,newRef:"Hunter 

350",hue:"#191919",hue2:"#C8102E",type:"Roadster",power:"20.2 bhp"},

   {id:5,acc:["Backrest","Windscreen","Touring mirrors"],km:"14,320 km",owner:"1st Owner",insValid:"Nov 

2026",shortlisted:10,year:2020,status:"sold",arrived:"2026-06-25",name:"Meteor 350",variant:"Supernova 

Brown",div:"Bengaluru",reg:"KA05LB4129",cc:350,asking:108000,market:135000,newPrice:260000,newRef:"Meteor 

350",hue:"#6E3F23",hue2:"#D8A868",type:"Tourer",power:"20.2 bhp"},

   {id:6,acc:["Engine guard","Pillion backrest"],km:"8,610 km",owner:"1st Owner",insValid:"Apr 

2027",shortlisted:8,year:2021,arrived:"2026-07-08",name:"Classic 350",variant:"Halcyon 

Green",div:"Bengaluru",reg:"KA05LF1459",cc:350,asking:130000,market:158000,newPrice:240000,newRef:"Classic 

350",hue:"#2E5C43",hue2:"#C9A84C",type:"Cruiser",power:"20.2 bhp"},

   {id:7,acc:["Crash guard","Tank strap"],km:"16,780 km",owner:"1st Owner",insValid:"Aug 

2026",shortlisted:6,year:2020,arrived:"2026-06-20",name:"Bullet 350",variant:"EFI 

Black",div:"Bengaluru",reg:"KA05LB3819",cc:350,asking:88000,market:110000,newPrice:210000,newRef:"Bullet 

350",hue:"#141414",hue2:"#C9A84C",type:"Classic",power:"19.1 bhp"},

   {id:8,acc:["Sump guard","Fog lamps"],km:"7,890 km",owner:"1st Owner",insValid:"Jun 

2027",shortlisted:4,year:2022,arrived:"2026-06-18",name:"Scram 411",variant:"Graphite 

Yellow",div:"Bengaluru",reg:"KAO5LJ4715",cc:411,asking:122000,market:148000,newPrice:270000,newRef:"Scram 

440",hue:"#E8B400",hue2:"#2b2b2e",type:"Scrambler",power:"24.3 bhp"},

   {id:9,acc:["Panniers + stays","Touring windscreen","Sump guard"],km:"10,102 km",owner:"1st Owner",insValid:"Feb 2027

",shortlisted:2,year:2022,status:"booked",bookedOn:"2026-07-06",arrived:"2026-07-05",name:"Himalayan",variant:"Lake 

Blue",div:"Bengaluru",reg:"KA05LM8712",cc:411,asking:162000,market:195000,newPrice:390000,newRef:"Himalayan 

450",hue:"#3E7CB8",hue2:"#1c3a58",type:"Adventure",power:"24.3 bhp"},

   {id:10,acc:["Crash guard","Tank pad"],km:"7,340 km",owner:"1st Owner",insValid:"Oct 

2027",shortlisted:9,year:2022,arrived:"2026-06-15",name:"Hunter 350",variant:"Rebel 

Black",div:"Bengaluru",reg:"KA05LM6886",cc:350,asking:122000,market:148000,newPrice:177000,newRef:"Hunter 

350",hue:"#191919",hue2:"#C8102E",type:"Roadster",power:"20.2 bhp"},

   {id:11,acc:["Engine guard","Flyscreen","Bar-end mirrors"],km:"9,120 km",owner:"1st Owner",insValid:"May 

2027",shortlisted:7,year:2022,arrived:"2026-07-02",name:"Interceptor 650",variant:"Downtown 

Drag",div:"Bengaluru",reg:"KAO5LM8668",cc:650,asking:242000,market:290000,newPrice:425000,newRef:"Interceptor 

650",hue:"#55565a",hue2:"#1b1b1d",type:"Roadster",power:"47 bhp"},

   {id:12,acc:["Flyscreen","Bar-end mirrors","Seat cowl"],km:"5,480 km",owner:"1st Owner",insValid:"Dec 

2027",shortlisted:5,year:2023,arrived:"2026-06-30",name:"GT 640 Rocker",variant:"Red",div:"Bengaluru",reg:"KA05LR1555",

cc:640,asking:268000,market:310000,newPrice:450000,newRef:"Continental GT 

650",hue:"#B01E28",hue2:"#F2E6C8",type:"Caf�� Racer",power:"47 bhp"},

  ];

  // photos live in memory: {gallery:[dataURL...], spin:[dataURL...]}

  const media={}; BIKES.forEach(b=>media[b.id]={gallery:[],spin:[],videos:[]});

  

  const fmt=n=>"� �"+Number(n).toLocaleString("en-IN");

  function listId(b){return "REO-"+String(b.id).padStart(3,"0");}

  function maskReg(r){return r.slice(0,2)+"-"+r.slice(2,4)+"-******";}

  function dispReg(b){return admin?b.reg:maskReg(b.reg);}

  const CHECKS=[

   {t:"Engine & compression",pts:38,subs:["Cold-start test","Compression reading","Oil condition & leak 

check","Abnormal noise / vibration","Clutch engagement & play"]},

   {t:"Chain & sprocket",pts:16,subs:["Chain slack & lubrication","Sprocket teeth wear","Chain stretch 

measurement","Rear hub & cush drive"]},

   {t:"Brakes & pads",pts:24,subs:["Front & rear pad depth","Disc condition & thickness","Brake fluid level & 

colour","ABS function test","Lever & pedal free play"]},

   {t:"Tyres & tread",pts:14,subs:["Tread depth (both tyres)","Sidewall cracks & tyre age","Correct pressure","Rim 

trueness ��   no bends"]},

   {t:"Battery health",pts:10,subs:["Voltage & load test","Terminal corrosion check","Charging output (regulator)"]},

   {t:"Electricals & lights",pts:30,subs:["Headlamp, tail & indicators","Horn & switches","Console & warning 

lights","Wiring, fuses & starter motor"]},

   {t:"Frame & body",pts:26,subs:["Chassis straightness","Accident / re-weld marks","Rust & corrosion points","Tank 

dents & paint condition"]},

   {t:"Suspension",pts:18,subs:["Front fork seals & travel","Rear shock damping & leaks","Steering bearing play"]},

   {t:"Odometer verified",pts:10,subs:["Km matched with service records","Tampering inspection","Full service history 

reviewed"]},

   {t:"RC & insurance",pts:14,subs:["Original RC ��   chassis no. matched","Insurance validity","No hypothecation or 

pending challans","Ownership count verified"]},

  ];

  

  let admin=false, chip="all";

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � PLACEHOLDER ART �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function art(b){

   const c=b.hue, a=b.hue2||"#C9A84C";

   return `<svg class="ph-art" viewBox="0 0 400 240" fill="none" style="opacity:.95;">

    <defs>

     <linearGradient id="tank${b.id}" x1="0" y1="0" x2="0" y2="1">

      <stop offset="0%" stop-color="${c}"/><stop offset="55%" stop-color="${c}"/><stop offset="100%" stop-color="#000" 

stop-opacity=".45"/>

     </linearGradient>

     <radialGradient id="glow${b.id}" cx="50%" cy="60%" r="65%">

      <stop offset="0%" stop-color="${c}" stop-opacity=".14"/><stop offset="100%" stop-color="${c}" stop-opacity="0"/>

     </radialGradient>

    </defs>

    <rect x="0" y="0" width="400" height="240" fill="url(#glow${b.id})" rx="16"/>

    <ellipse cx="205" cy="212" rx="185" ry="12" fill="#000" opacity=".08"/>

    <circle cx="95" cy="175" r="52" stroke="#1c1c1e" stroke-width="8"/>

    <circle cx="95" cy="175" r="26" stroke="#8a8a90" stroke-width="2.5"/>

    <circle cx="95" cy="175" r="6" fill="#1c1c1e"/>

    <circle cx="315" cy="175" r="52" stroke="#1c1c1e" stroke-width="8"/>

    <circle cx="315" cy="175" r="26" stroke="#8a8a90" stroke-width="2.5"/>

    <circle cx="315" cy="175" r="6" fill="#1c1c1e"/>

    <path d="M95 123 L145 78 L215 62 L275 72 L315 123" stroke="#232326" stroke-width="6"/>

    <path d="M145 78 L172 123 L95 123" stroke="#232326" stroke-width="4.5"/>

    <ellipse cx="222" cy="72" rx="58" ry="21" fill="url(#tank${b.id})" stroke="#141414" stroke-width="2.5"/>

    <ellipse cx="222" cy="70" rx="34" ry="9" fill="#fff" opacity=".18"/>

    <path d="M170 74 Q222 60 274 74" stroke="${a}" stroke-width="2.5" opacity=".95"/>

    <circle cx="222" cy="72" r="7" fill="${a}" opacity=".9"/>

    <path d="M160 84 Q222 70 284 84" stroke="#141414" stroke-width="4.5"/>

    <path d="M275 72 L302 48 L330 44" stroke="#232326" stroke-width="4"/>

    <circle cx="322" cy="86" r="13" fill="#F2E9CE" stroke="#232326" stroke-width="3"/>

    <rect x="168" y="102" width="66" height="46" rx="7" fill="#3a3a3e" stroke="#141414" stroke-width="2"/>

    <rect x="176" y="108" width="50" height="6" rx="3" fill="#6a6a70"/>

    <rect x="176" y="120" width="50" height="6" rx="3" fill="#6a6a70"/>

    <path d="M172 162 Q130 158 100 182" stroke="#9a9aa0" stroke-width="5"/>

    <path d="M330 82 L348 82" stroke="${a}" stroke-width="3"/>

   </svg>`;

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � GRID �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function matches(b){

   if(chip==="all")return true;

   if(chip==="350")return b.cc===350;

   if(chip==="411")return b.cc===411;

   if(chip==="650")return b.cc>=640;

   if(chip==="under15")return b.asking<150000;

   return true;

  }

  function setChip(f,el){chip=f;document.querySelectorAll(".chip").forEach(c=>c.classList.remove("on"));el.classList.ad

d("on");renderGrid();}

  

  /* status: available (default) | booked (20% paid, 7-day hold) | sold */

  function stat(b){return b.status||"available";}

  function holdDaysLeft(b){

   if(stat(b)!=="booked"||!b.bookedOn)return 0;

   return Math.max(0,7-Math.floor((Date.now()-new Date(b.bookedOn))/864e5));

  }

  const STATUS_ORDER={available:0,booked:1,sold:2};

  

  function visibleToPublic(b){return b.approval!=="pending"&&b.approval!=="denied";}

  function renderGrid(){

   const g=document.getElementById("grid");

   const pool=BIKES.filter(b=>admin?true:visibleToPublic(b));

   const APPR_ORDER={pending:0,undefined:1,approved:1,denied:2};

   const sorted=pool.filter(matches).sort((a,b)=>

    (admin?(APPR_ORDER[a.approval]-APPR_ORDER[b.approval]):0)||(STATUS_ORDER[stat(a)]-STATUS_ORDER[stat(b)]));

   g.innerHTML=sorted.map((b,i)=>{

    const m=media[b.id];

    const cover=m.gallery[0]||m.spin[0];

    const nPhotos=m.gallery.length+m.spin.length;

    return `<div class="card ${admin?'admin':''} st-${stat(b)}" style="animation-delay:${i*.04}s" 

onclick="openDetail(${b.id})">

     <div class="card-media">

      ${cover?`<img src="${cover}" alt="${b.name}"/>`:art(b)}

      ${stat(b)==="available"?'<div class="card-tag">Available</div>':''}

      ${stat(b)==="booked"?`<div class="card-tag tag-booked">Booked �� ${holdDaysLeft(b)}d hold</div>`:''}

      ${stat(b)==="sold"?'<div class="card-tag tag-sold">Sold</div>':''}

      ${admin&&b.approval==="pending"?'<div class="card-tag" style="top:44px;color:#a06a00;">��� Pending 

approval</div>':''}

      ${admin&&b.approval==="denied"?'<div class="card-tag tag-sold" style="top:44px;">�S"  Denied</div>':''}

      ${m.spin.length>1?`<div class="tag-360">�  � 360��</div>`:''}

      ${m.videos&&m.videos.length?`<div class="tag-360" style="top:${m.spin.length>1?'42':'14'}px;">� � 

Video</div>`:''}

      ${nPhotos?`<div class="photo-count">${nPhotos} photos</div>`:''}

      ${admin?`<div class="upload-hint" onclick="event.stopPropagation();openUpload(${b.id})">

        <svg fill="none" stroke-width="2" viewBox="0 0 24 24"><path d="M3 16.5V19a2 2 0 002 2h14a2 2 0 002-2v-2.5M12 

3v13m0-13l-4 4m4-4l4 4" stroke-linecap="round" stroke-linejoin="round"/></svg>

        ${nPhotos?'Manage photos':'Add photos'}

      </div>`:''}

     </div>

     <div class="card-body">

      <div class="card-name">${b.name} <span class="card-variant">${b.variant}</span></div>

      <div class="card-meta"><span 

style="color:var(--gold);font-weight:700;">${listId(b)}</span><span>��</span><span><b style="color:var(--ink2);">${b.ye

ar}</b></span><span>��</span><span>${b.km}</span><span>��</span><span>${b.owner}</span><span>��</span><span>${dispReg(b

)}</span></div>

      ${b.acc&&b.acc.length?`<div class="acc-chips">${b.acc.map(a=>`<span class="acc-chip">��9  

${a}</span>`).join("")}</div>`:''}

      <div class="card-foot">

       <div>

        <div class="card-was">New: ${fmt(b.newPrice)} on-road</div>

        <div class="card-price">${fmt(b.asking)}</div>

        <div class="card-save">${Math.round((1-b.asking/b.newPrice)*100)}% below new �� save 

${fmt(b.newPrice-b.asking)}</div>

       </div>

       <button class="btn btn-dark btn-sm" onclick="event.stopPropagation();openDetail(${b.id})">View</button>

      </div>

      ${admin&&can.approve()&&b.approval==="pending"?`

       <div style="display:flex;gap:8px;margin-top:12px;" onclick="event.stopPropagation()">

        <button class="btn btn-sm" style="flex:1;background:var(--green);color:#fff;justify-content:center;" 

onclick="approveBike(${b.id})">�S  Approve</button>

        <button class="btn btn-sm" style="flex:1;background:#b03030;color:#fff;justify-content:center;" 

onclick="denyBike(${b.id})">�S"  Deny</button>

       </div>`:''}

      ${admin&&can.del()&&b.approval!=="pending"?`

       <div style="display:flex;gap:8px;margin-top:12px;" onclick="event.stopPropagation()">

        <button class="btn btn-sm btn-light" style="flex:1;justify-content:center;" onclick="editPrice(${b.id})">�S} 

Price</button>

        <button class="btn btn-sm" style="background:transparent;border:1.5px solid #ecc0c0;color:#b03030;" 

onclick="deleteBike(${b.id})">�x  </button>

       </div>`:''}

     </div>

    </div>`;

   }).join('');

  }

  

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � STAFF: SHARE BIKE DETAILS �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function shareBike(id){

   const b=BIKES.find(x=>x.id===id);

   const dep=fmt(Math.round(b.asking*0.2/500)*500);

   const msg=[

    "�x����� *REOWN �� Avahan Motors ��   Bengaluru*","",

    "*"+b.name+" "+b.variant+"*",

    "Listing ID: "+listId(b),

    "��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ",

    "�x &  Model Year: "+b.year,

    "�x: ���� Kms Driven: "+b.km,

    "�x � Owner: "+b.owner,

    "�x: ���� Insurance valid till: "+b.insValid,

    "�x 9  Reg No: "+b.reg,

    (b.acc&&b.acc.length?"�x}� Accessories FREE: "+b.acc.join(", "):null),

    "��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ",

    "�x � *Price: "+fmt(b.asking)+"*",

    "�x  "  Same bike new (on-road): "+fmt(b.newPrice)+" ��   you save "+fmt(b.newPrice-b.asking),

    "�x � EMI from ~"+fmt(Math.round((b.asking*0.8*0.0108*Math.pow(1.0108,36))/(Math.pow(1.0108,36)-1)))+"/mo",

    "�x   Block + test ride: 10% ("+fmt(Math.round(b.asking*0.1/500)*500)+") ��   love it? top up 10% to reserve �� not 

convinced? 10% auto-refunded",

    "�x   Reserve 7 days (finance & delivery): 20% ("+dep+") ��   auto-refund if not completed",

    "��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ��  ",

    "�S&  Reown 200-checkpoint certified",

    "�a� Delivered in 100 mins (Bengaluru)",

    "�  ���� 6-month buyback @ 80% (under 5,000 km)",

    "",

    "�x ~ Re-Own Expert Line: +91 90350 45535",

   ].filter(Boolean).join("\n");

   logEvt("Shared bike details",b.name+" ("+listId(b)+")");

   window.open("https://wa.me/?text="+encodeURIComponent(msg),"_blank");

  }

  

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � PHONE DIALER �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  const PHONE="+919035045535";

  function callUs(){

   logEvt("Call tapped","");

   try{window.location.href="tel:"+PHONE;}

   catch(err){window.open("tel:"+PHONE,"_self");}

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � STAFF ROLES (password-protected) �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  /* �  � change passwords here */

  const ROLE_PINS={"exec2026":"Executive","mgr2026":"Manager","dir2026":"Director","reown2026":"Manager"};

  let role=null;

  const can={

   upload:()=>!!role,

   addBike:()=>!!role,

   approve:()=>role==="Manager"||role==="Director",

   edit:()=>role==="Manager"||role==="Director",

   del:()=>role==="Manager"||role==="Director",

   monitor:()=>role==="Director",

  };

  /* activity log */

  const activity=[];

  function logEvt(action,detail){

   activity.push({t:new Date(),role:role||"Visitor",action,detail:detail||""});

   const reqs=JSON.parse(localStorage.getItem("requests")||"[]");

   reqs.push({t:new Date().toISOString(),action,detail});

   localStorage.setItem("requests",JSON.stringify(reqs));

  }

  logEvt("Site opened","");

  

  function toggleAdmin(){

   if(!admin && !role){

    document.getElementById("pinInput").value="";

    document.getElementById("pinErr").style.display="none";

    document.getElementById("pinOv").classList.add("open");

    setTimeout(()=>document.getElementById("pinInput").focus(),100);

    return;

   }

   if(admin){logEvt("Logout",role);role=null;}

   setAdmin(!admin);

  }

  function checkPin(){

   const v=document.getElementById("pinInput").value;

   if(ROLE_PINS[v]){

    role=ROLE_PINS[v];

    logEvt("Login",role);

    document.getElementById("pinOv").classList.remove("open");

    setAdmin(true);

   }else{

    const err=document.getElementById("pinErr");

    err.style.display="block";

    const sh=document.getElementById("pinSheet");

    sh.style.animation="none";sh.offsetHeight;

    sh.style.animation="shake .4s";

   }

  }

  function setAdmin(on){

   admin=on;

   document.getElementById("adminBtn").classList.toggle("on",admin);

   document.getElementById("adminLabel").textContent=admin?(role+" �� logout"):"Staff login";

   renderGrid();

   document.getElementById("heroUploadBtn").style.display=admin?"block":"none";

   const da=document.getElementById("dwallAdd");if(da)da.style.display=admin?"inline-flex":"none";

   const ab=document.getElementById("addBikeBtn");if(ab)ab.style.display=admin?"inline-flex":"none";

   const mb=document.getElementById("monitorBtn");if(mb)mb.style.display=(admin&&can.monitor())?"inline-flex":"none";

   showToast(admin?("Signed in as "+role):"Signed out");

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � UPLOAD MANAGER �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  let upBikeId=null, upTab="gallery";

  function openUpload(id){

   upBikeId=id; upTab="gallery";

   const b=BIKES.find(x=>x.id===id);

   document.getElementById("upTitle").textContent=b.name+" �� "+b.variant;

   document.getElementById("upSub").textContent=b.reg+" ��   photos appear instantly on the listing";

   renderStPills(b);

   setUpTab("gallery");

   document.getElementById("uploadOv").classList.add("open");

  }

  function closeUpload(){document.getElementById("uploadOv").classList.remove("open");renderGrid();}

  function setUpTab(t){

   upTab=t;

   document.getElementById("tabGal").classList.toggle("on",t==="gallery");

   document.getElementById("tab360").classList.toggle("on",t==="spin");

   document.getElementById("tabVid").classList.toggle("on",t==="video");

   const f=document.getElementById("upFile");

   f.accept=t==="video"?"video/*":"image/*";

   document.getElementById("dzTitle").textContent=

     t==="gallery"?"Drop gallery photos here":t==="spin"?"Drop your 360�� frame sequence here":"Drop a walkaround / 

start-up video here";

   document.getElementById("dzSub").innerHTML=

     t==="gallery"?'or <b>browse</b> ��   JPG / PNG. Tap the star on any photo to make it the cover.'

     :t==="spin"?'or <b>browse</b> ��   select all 24��  36 frames at once. They sort by filename automatically.'

     :'or <b>browse</b> ��   MP4 / MOV, up to ~60s works best. Engine start-up + walkaround sells bikes.';

   document.getElementById("tipText").textContent=

     t==="gallery"?"Shoot landscape, consistent height, plain background. 6��  10 photos per bike is ideal."

     :t==="spin"?"Shoot 1 frame every 10��  15�� on a turntable (24��  36 total). Name files 01.jpg, 02.jpg�� � and the 

spin plays perfectly."

     :"One take, phone in landscape: cold start, exhaust note, slow walkaround, close-up of odometer. 30��  60 

seconds.";

   renderUpPreviews();

  }

  // drag & drop

  const upDrop=document.getElementById("upDrop");

  ["dragover","dragenter"].forEach(e=>upDrop.addEventListener(e,ev=>{ev.preventDefault();upDrop.classList.add("drag");}

));

  

["dragleave","drop"].forEach(e=>upDrop.addEventListener(e,ev=>{ev.preventDefault();upDrop.classList.remove("drag");}));

  upDrop.addEventListener("drop",ev=>handleUpload(ev.dataTransfer.files));

  

  function handleUpload(files){

   if(!files||!files.length)return;

   if(upTab==="video"){

    const vids=[...files].filter(f=>f.type.startsWith("video/"));

    let n=0;

    vids.forEach(f=>{

     const r=new FileReader();

     r.onload=e=>{media[upBikeId].videos.push(e.target.result);n++;

      if(n===vids.length){renderUpPreviews();showToast(n+" video"+(n>1?"s":"")+" added");}};

     r.readAsDataURL(f);

    });

    document.getElementById("upFile").value="";

    return;

   }

   const arr=[...files].filter(f=>f.type.startsWith("image/"));

   arr.sort((a,b)=>a.name.localeCompare(b.name,undefined,{numeric:true}));

   let loaded=0;

   arr.forEach(f=>{

    const r=new FileReader();

    r.onload=e=>{

     media[upBikeId][upTab==="gallery"?"gallery":"spin"].push(e.target.result);

     loaded++;

     if(loaded===arr.length){renderUpPreviews();logEvt("Uploaded "+(upTab==="gallery"?"photos":"360 frames"),loaded+" 

file(s) ��   bike #"+upBikeId);showToast(loaded+(upTab==="gallery"?" photo":" frame")+(loaded>1?"s":"")+" added");}

    };

    r.readAsDataURL(f);

   });

   document.getElementById("upFile").value="";

  }

  function removeMedia(kind,i){media[upBikeId][kind].splice(i,1);renderUpPreviews();}

  function renderUpPreviews(){

   const m=media[upBikeId]||{gallery:[],spin:[],videos:[]};

   document.getElementById("cntGal").textContent=m.gallery.length;

   document.getElementById("cnt360").textContent=m.spin.length;

   document.getElementById("cntVid").textContent=(m.videos||[]).length;

   if(upTab==="video"){

    document.getElementById("upPreviews").innerHTML=(m.videos||[]).map((src,i)=>`

     <div class="pv" style="aspect-ratio:16/9;">

      <video src="${src}" muted style="width:100%;height:100%;object-fit:cover;"></video>

      <div class="pv-n">� � Video ${i+1}</div>

      <button class="pv-x" onclick="removeMedia('videos',${i})">�S" </button>

     </div>`).join('');

    return;

   }

   const list=upTab==="gallery"?m.gallery:m.spin;

   document.getElementById("upPreviews").innerHTML=list.map((src,i)=>`

    <div class="pv">

     <img src="${src}"/>

     ${upTab==="gallery"?(i===0?'<div class="pv-cover">��&  COVER</div>':`<button class="pv-star" 

onclick="setCover(${i})" title="Make this the cover">��   Set cover</button>`):''}

     ${upTab==="spin"?`<div class="pv-n">${i+1}</div>`:''}

     <button class="pv-x" onclick="removeMedia('${upTab==="gallery"?"gallery":"spin"}',${i})">�S" </button>

    </div>`).join('');

  }

  function setCover(i){

   const g=media[upBikeId].gallery;

   g.unshift(g.splice(i,1)[0]);

   renderUpPreviews();

   showToast("Cover photo updated");

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � DETAIL + VIEWER �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  let curId=null, mode="gallery", galIdx=0, spinIdx=0, dragging=false, dragX=0, dragStart=0;

  

  function openDetail(id){

   curId=id;

   const _b=BIKES.find(x=>x.id===id);if(_b){_b.views=(_b.views||0)+1;logEvt("Viewed bike",_b.name+" ("+_b.reg+")");} 

galIdx=0; spinIdx=0;

   const b=BIKES.find(x=>x.id===id);

   const m=media[id];

   mode=m.spin.length>1?"spin":"gallery";

  

  

   document.getElementById("detailInner").innerHTML=`

    <div class="viewer">

     <div class="stage" id="stage"></div>

     <div class="mode-pill">

      <button class="mode-btn ${mode==='gallery'?'on':''}" id="mGal" onclick="setMode('gallery')">Photos</button>

      <button class="mode-btn ${mode==='spin'?'on':''}" id="mSpin" onclick="setMode('spin')">360�� spin</button>

      ${media[b.id].videos&&media[b.id].videos.length?`<button class="mode-btn" id="mVid" 

onclick="setMode('video')">� � Video</button>`:''}

     </div>

     <div class="deg-badge" id="degBadge" style="display:none;">0��</div>

     <button class="gallery-nav gnav-l" id="gnavL" onclick="galStep(-1)">�� �</button>

     <button class="gallery-nav gnav-r" id="gnavR" onclick="galStep(1)">�� �</button>

     <div class="drag-hint" id="dragHint" style="display:none;">�  � &nbsp;Drag to spin</div>

     <div class="frame-bar" id="frameBar" style="display:none;"><div class="frame-fill" id="frameFill"></div></div>

    </div>

    <div class="thumbs" id="thumbs"></div>

    <div class="detail-body">

     <div class="detail-left">

      <div class="d-name">${b.name}</div>

      <div class="d-variant"><span style="color:var(--gold);font-weight:700;">${listId(b)}</span> �� ${b.variant} �� 

${b.year} model �� Bengaluru</div>

      <div style="display:flex;align-items:center;gap:10px;margin:-8px 0 16px;">

       <button style="font-size:20px;line-height:1;" id="heartBtn" 

onclick="toggleShortlist(${b.id})">${b.hearted?'������':'�x��'}</button>

       <span style="font-size:12.5px;font-weight:600;color:var(--gold);" id="shortCount">${b.shortlisted} people have 

shortlisted this bike</span>

      </div>

      <div class="spec-row" style="grid-template-columns:repeat(3,1fr);">

       <div class="spec"><b>${b.km}</b><span>Kms Driven</span></div>

       <div class="spec"><b>${b.year}</b><span>Model Year</span></div>

       <div class="spec"><b>${b.owner}</b><span>Owner</span></div>

       <div class="spec"><b>${b.insValid}</b><span>Insurance Valid</span></div>

       <div class="spec"><b>${b.cc}cc</b><span>Engine</span></div>

       <div class="spec"><b>${dispReg(b)}</b><span>Reg No</span></div>

      </div>

      ${b.acc&&b.acc.length?`

      <div class="d-label">Accessories included ��   free with this bike</div>

      <div class="acc-chips" style="margin:-4px 0 22px;">${b.acc.map(a=>`<span class="acc-chip acc-chip-lg">��9  

${a}</span>`).join("")}</div>`:''}

      <div class="d-label">Reown 200-checkpoint certification ��   all passed �� 10 categories, tap to expand</div>

      <div class="acc">

       ${CHECKS.map((c,i)=>`

        <div class="acc-item" id="acc${i}">

         <button class="acc-head" onclick="toggleAcc(${i})">

          <span style="display:flex;align-items:center;gap:10px;">

           <svg fill="none" stroke-width="2.5" viewBox="0 0 24 24" 

style="width:17px;height:17px;stroke:var(--green);flex-shrink:0;"><path d="M5 13l4 4L19 7" stroke-linecap="round" 

stroke-linejoin="round"/></svg>

           ${c.t}

          </span>

          <span style="display:flex;align-items:center;gap:8px;">

           <span style="font-size:10.5px;font-weight:700;background:var(--green-bg);color:var(--green);padding:3px 

9px;border-radius:980px;">${c.pts} checks</span>

           <span class="acc-plus">+</span>

          </span>

         </button>

         <div class="acc-body">

          ${c.subs.map(s=>`<div class="acc-sub">�� ${s}</div>`).join('')}

         </div>

        </div>`).join('')}

      </div>

     </div>

     <div class="detail-right">

      <div class="d-label">Price</div>

      <div class="d-price">${fmt(b.asking)}</div>

      <div class="d-was"><s>${fmt(b.market)}</s><span class="d-save">used market avg</span></div>

      <div style="margin-top:14px;background:#fff;border:1.5px solid 

var(--line);border-radius:var(--radius-sm);padding:14px 16px;">

       <div style="display:flex;justify-content:space-between;font-size:13px;padding:5px 0;">

        <span style="color:var(--ink3);">New ${b.newRef} (on-road, BLR)</span><b>${fmt(b.newPrice)}</b>

       </div>

       <div style="display:flex;justify-content:space-between;font-size:13px;padding:5px 0;border-top:1px solid 

var(--line);">

        <span style="color:var(--ink3);">This bike</span><b>${fmt(b.asking)}</b>

       </div>

       <div style="display:flex;justify-content:space-between;font-size:13.5px;padding:7px 0 2px;border-top:1px solid 

var(--line);">

        <b style="color:var(--green);">You save vs new</b><b style="color:var(--green);">${fmt(b.newPrice-b.asking)} 

(${Math.round((1-b.asking/b.newPrice)*100)}%)</b>

       </div>

      </div>

      <div class="emi-box">

       <div class="d-label" style="margin-bottom:4px;">EMI calculator</div>

       <div class="emi-num" id="emiNum"></div>

       <div style="margin-top:10px;">

        <div 

style="display:flex;justify-content:space-between;font-size:11.5px;font-weight:600;color:var(--ink3);"><span>Down 

payment</span><span id="dpLabel"></span></div>

        <input type="range" id="dpSlider" min="10" max="60" step="5" value="20" oninput="calcEmi(${b.asking})"/>

        <div style="display:flex;justify-content:space-between;font-size:11.5px;font-weight:600;color:var(--ink3);"><sp

an>Tenure</span><span id="tenLabel"></span></div>

        <input type="range" id="tenSlider" min="6" max="48" step="6" value="24" oninput="calcEmi(${b.asking})"/>

        <div 

style="display:flex;justify-content:space-between;font-size:11.5px;font-weight:600;color:var(--ink3);"><span>Interest 

rate</span><span id="rateLabel"></span></div>

        <input type="range" id="rateSlider" min="9" max="18" step="0.5" value="13" oninput="calcEmi(${b.asking})"/>

       </div>

       <div class="emi-note" id="emiBreak"></div>

      </div>

      ${stat(b)==="booked"?`<div class="status-banner sb-booked">��� Reserved ��   20% received. ${holdDaysLeft(b)} 

day${holdDaysLeft(b)===1?"":"s"} left to complete finance/payment & delivery. If not completed, the amount is 

auto-refunded and the bike returns to Available.</div>`:''}

      ${stat(b)==="sold"?'<div class="status-banner sb-sold">�S"  Sold ��   this motorcycle has found its rider. Similar 

stock arrives weekly.</div>':''}

      <div class="stack">

       ${stat(b)==="available"?`<button class="btn btn-gold btn-block" style="background:var(--gold);" 

onclick="openRules(${b.id})">�a� Buy online (RTGS) �� Delivered in 100 mins</button>`:''}

       ${stat(b)==="available"?`<button class="btn btn-block" 

style="background:var(--mustard);color:#141412;justify-content:center;" onclick="openRules(${b.id})">Block + test ride 

�� 10% (${fmt(Math.round(b.asking*0.1/500)*500)}) ��   refundable</button>`:''}

       ${stat(b)==="available"?`<button class="btn btn-block btn-light" style="justify-content:center;" 

onclick="openRules(${b.id})">Reserve 7 days �� 20% (${fmt(Math.round(b.asking*0.2/500)*500)}) ��   finance & 

delivery</button>`:''}

       ${stat(b)==="available"?`<button class="btn btn-dark btn-block" style="background:var(--ink);" 

onclick="openBook(${b.id})">Book test ride</button>`:''}

       ${stat(b)==="booked"?`<button class="btn btn-light btn-block" onclick="showToast('Added to waitlist ��   we\\'ll 

message if this booking releases')">Join waitlist ��   notify if released</button>`:''}

       ${stat(b)==="sold"?`<button class="btn btn-light btn-block" onclick="showToast('Noted! We\\'ll WhatsApp you 

when a similar ${b.name} arrives')">Notify me when similar arrives</button>`:''}

       <a class="btn btn-light btn-block" style="justify-content:center;text-decoration:none;" 

href="tel:+919035045535" onclick="callUs();return false;">�x ~ Call +91 90350 45535</a>

       ${admin?`<button class="btn btn-block" style="background:#141412;color:#fff;justify-content:center;" 

onclick="shareBike(${b.id})">�x � Send bike details on WhatsApp</button>`:''}

       <button class="btn btn-gold btn-block" 

onclick="window.open('https://wa.me/919035045535?text='+encodeURIComponent('Hi! I\\'m interested in the ${b.name} 

${b.variant} (${dispReg(b)}) at ${fmt(b.asking)}.'),'_blank')">Enquire on WhatsApp</button>

       ${admin?`<button class="btn btn-light btn-block" onclick="closeDetail();openUpload(${b.id})">��   Manage photos 

(dealer)</button>`:''}

      </div>

      <div style="display:flex;flex-wrap:wrap;gap:6px;margin-top:16px;">

       <span style="font-size:11px;font-weight:700;background:var(--gold-bg);color:var(--gold-dark);padding:5px 

11px;border-radius:var(--pill);">�a� 100-min BLR delivery</span>

       <span style="font-size:11px;font-weight:700;background:var(--mustard-bg);color:#7a5c00;padding:5px 

11px;border-radius:var(--pill);">�  � 6-mo buyback @ 80%</span>

       <span style="font-size:11px;font-weight:700;background:var(--green-bg);color:var(--green);padding:5px 

11px;border-radius:var(--pill);">�!   Instant exchange</span>

      </div>

      <div style="margin-top:12px;" class="mono">Reown Certified �� Chassis-verified �� Ref 11269V</div>

      <button style="margin-top:8px;font-size:12.5px;font-weight:600;color:var(--gold);text-decoration:underline;" 

onclick="openRules()">How booking works ��   the Re-Own rules �   </button>

     </div>

    </div>`;

  

   document.getElementById("detailOv").classList.add("open");

   document.getElementById("detailOv").scrollTop=0;

   bindStage();

   setMode(mode);

   calcEmi(b.asking);

  }

  function closeDetail(){document.getElementById("detailOv").classList.remove("open");}

  

  function setMode(m){

   const b=BIKES.find(x=>x.id===curId), md=media[curId];

   mode=m;

   document.getElementById("mGal").classList.toggle("on",m==="gallery");

   document.getElementById("mSpin").classList.toggle("on",m==="spin");

   const mv=document.getElementById("mVid"); if(mv)mv.classList.toggle("on",m==="video");

   const hasSpin=md.spin.length>1, hasGal=md.gallery.length>0;

   document.getElementById("degBadge").style.display=m==="spin"&&hasSpin?"block":"none";

   document.getElementById("dragHint").style.display=m==="spin"&&hasSpin?"flex":"none";

   document.getElementById("frameBar").style.display=m==="spin"&&hasSpin?"block":"none";

   document.getElementById("gnavL").style.display=m==="gallery"&&md.gallery.length>1?"flex":"none";

   document.getElementById("gnavR").style.display=m==="gallery"&&md.gallery.length>1?"flex":"none";

   renderStage(); renderThumbs();

  }

  

  function renderStage(){

   const b=BIKES.find(x=>x.id===curId), md=media[curId], st=document.getElementById("stage");

   if(mode==="video"){

    st.innerHTML=md.videos.length

     ?`<video src="${md.videos[0]}" controls playsinline 

style="width:100%;height:100%;object-fit:contain;background:#000;"></video>`

     :`<div class="empty-stage">${art(b)}<p>No video yet</p></div>`;

    return;

   }

   if(mode==="spin"){

    if(md.spin.length>1){

     st.innerHTML=`<img src="${md.spin[spinIdx]}" draggable="false"/>`;

     const deg=Math.round(spinIdx/md.spin.length*360);

     document.getElementById("degBadge").textContent=deg+"��";

     document.getElementById("frameFill").style.width=(spinIdx/(md.spin.length-1)*100)+"%";

    }else{

     st.innerHTML=`<div class="empty-stage">${art(b)}<p>No 360�� frames yet${admin?' ��   switch to dealer upload to 

add a spin':''}</p>

      ${admin?`<button class="btn btn-gold btn-sm" onclick="closeDetail();openUpload(${b.id})">Upload 360�� 

frames</button>`:''}</div>`;

    }

   }else{

    if(md.gallery.length){

     st.innerHTML=`<img src="${md.gallery[galIdx]}" draggable="false"/>`;

    }else{

     st.innerHTML=`<div class="empty-stage">${art(b)}<p>Professional photos coming soon${admin?'':' ��   enquire for a 

live video call inspection'}</p>

      ${admin?`<button class="btn btn-gold btn-sm" onclick="closeDetail();openUpload(${b.id})">Upload 

photos</button>`:''}</div>`;

    }

   }

  }

  function renderThumbs(){

   const md=media[curId], t=document.getElementById("thumbs");

   if(mode==="video"){

    t.innerHTML=md.videos.map((src,i)=>`<div class="thumb ${i===0?'on':''}" onclick="playVid(${i})"><video 

src="${src}" muted style="width:100%;height:100%;object-fit:cover;"></video></div>`).join('')

     +(admin?`<div class="thumb thumb-add" onclick="closeDetail();openUpload(${curId})"><span 

style="font-size:16px;">+</span><span>Add</span></div>`:'');

    return;

   }

   if(mode==="gallery"){

    t.innerHTML=md.gallery.map((src,i)=>`<div class="thumb ${i===galIdx?'on':''}" 

onclick="galIdx=${i};renderStage();renderThumbs();"><img src="${src}"/></div>`).join('')

     +(admin?`<div class="thumb thumb-add" onclick="closeDetail();openUpload(${curId})"><span 

style="font-size:16px;">+</span><span>Add</span></div>`:'');

   }else{

    t.innerHTML=md.spin.length>1

     ?`<div style="font-size:12.5px;color:var(--ink3);padding:6px 4px;font-weight:500;">�  � ${md.spin.length} frames 

�� drag the image left or right to rotate</div>`

     :(admin?`<div class="thumb thumb-add" onclick="closeDetail();openUpload(${curId})" style="width:auto;padding:0 

16px;"><span>+ Upload 360�� frame set</span></div>`

            :`<div style="font-size:12.5px;color:var(--ink3);padding:6px 4px;">360�� spin being photographed ��   check 

back soon</div>`);

   }

  }

  function galStep(d){

   const md=media[curId]; if(!md.gallery.length)return;

   galIdx=(galIdx+d+md.gallery.length)%md.gallery.length;

   renderStage();renderThumbs();

  }

  function bindStage(){

   const st=document.getElementById("stage");

   const start=x=>{if(mode!=="spin")return;dragging=true;dragX=x;dragStart=spinIdx;st.classList.add("grabbing");};

   const move=x=>{

    if(!dragging||mode!=="spin")return;

    const md=media[curId]; if(md.spin.length<2)return;

    const per=Math.max(4, 320/md.spin.length); // px per frame

    let idx=Math.round(dragStart+(x-dragX)/per);

    spinIdx=((idx%md.spin.length)+md.spin.length)%md.spin.length;

    renderStage();

   };

   const end=()=>{dragging=false;st.classList.remove("grabbing");};

   st.onmousedown=e=>start(e.clientX);

   window.onmousemove=e=>move(e.clientX);

   window.onmouseup=end;

   st.ontouchstart=e=>start(e.touches[0].clientX);

   st.ontouchmove=e=>{move(e.touches[0].clientX);};

   st.ontouchend=end;

   // gallery swipe

   let gx=null;

   st.addEventListener("touchstart",e=>{if(mode==="gallery")gx=e.touches[0].clientX;});

   st.addEventListener("touchend",e=>{

    if(mode==="gallery"&&gx!==null){

     const dx=e.changedTouches[0].clientX-gx;

     if(Math.abs(dx)>40)galStep(dx<0?1:-1);

     gx=null;

    }

   });

  }

  function toggleAcc(i){

   document.getElementById("acc"+i).classList.toggle("open");

  }

  function emi(p,mo){const r=.014;return Math.round(p*.8*r*Math.pow(1+r,mo)/(Math.pow(1+r,mo)-1));}

  function pickEmi(btn,mo,price){

   btn.parentElement.querySelectorAll("button").forEach(b=>b.classList.remove("on"));

   btn.classList.add("on");

   document.getElementById("emiNum").innerHTML=fmt(emi(price,mo))+'<span 

style="font-size:14px;font-weight:600;color:var(--ink3);">/mo</span>';

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � BOOKING �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  const bookSel=document.getElementById("bookBike");

  BIKES.forEach(b=>{const o=document.createElement("option");o.value=b.id;o.textContent=`${b.name} ${b.variant} ��   

${maskReg(b.reg)}`;bookSel.appendChild(o);});

  function openBook(id){

   logEvt("Booking opened",id?("bike #"+id):"general");

   if(id)bookSel.value=id;

   closeDetail();

   document.getElementById("bookOv").classList.add("open");

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � SELL FLOW �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  const sellPhotos=[];

  function sellNext(step){

   [1,2,3].forEach(s=>{

    document.getElementById("sellStep"+s).style.display=s===step?"block":"none";

    const el=document.getElementById("st"+s);

    el.classList.toggle("on",s===step);

    el.classList.toggle("done",s<step);

   });

   if(step===1){sellPhotos.length=0;document.getElementById("sellPreviews").innerHTML="";}

  }

  const sellDrop=document.getElementById("sellDrop");

  ["dragover","dragenter"].forEach(e=>sellDrop.addEventListener(e,ev=>{ev.preventDefault();sellDrop.classList.add("drag

");}));

  ["dragleave","drop"].forEach(e=>sellDrop.addEventListener(e,ev=>{ev.preventDefault();sellDrop.classList.remove("drag"

);}));

  sellDrop.addEventListener("drop",ev=>addSellPhotos(ev.dataTransfer.files));

  function addSellPhotos(files){

   [...files].filter(f=>f.type.startsWith("image/")).forEach(f=>{

    const r=new FileReader();

    r.onload=e=>{sellPhotos.push(e.target.result);renderSellPreviews();};

    r.readAsDataURL(f);

   });

    const cam = document.getElementById("sellFileCam"); if(cam) cam.value="";

    const gal = document.getElementById("sellFileGal"); if(gal) gal.value="";

  }

  function renderSellPreviews(){

   document.getElementById("sellPreviews").innerHTML=sellPhotos.map((src,i)=>`

    <div class="pv"><img src="${src}"/><button class="pv-x" 

onclick="sellPhotos.splice(${i},1);renderSellPreviews();">�S" </button></div>`).join('');

  }

  function computeEstimate(){

   const base={"Classic 350":128000,"Bullet 350":92000,"Hunter 350":115000,"Meteor 350":112000,"Scram 

411":120000,"Himalayan":150000,"Interceptor 650":235000,"Continental GT 650":245000,"Other":100000};

   const yr={"2025":1.06,"2024":1.0,"2023":.92,"2022":.84,"2021":.76,"2020":.68,"2019":.6,"2018 or older":.5};

   const km={"Under 5,000 km":1.05,"5,000 ��   15,000 km":1.0,"15,000 ��   30,000 km":.92,"30,000 ��   50,000 

km":.82,"50,000+ km":.7};

   const cond={"Excellent ��   like new":1.06,"Good ��   minor wear":1.0,"Fair ��   visible wear":.88,"Needs work":.72};

   const v=Math.round(base[val("sModel")]*yr[val("sYear")]*km[val("sKm")]*cond[val("sCond")]/1000)*1000;

   document.getElementById("estValue").textContent=fmt(v);

   document.getElementById("estRange").textContent=`Range: ${fmt(Math.round(v*.94/1000)*1000)} ��   

${fmt(Math.round(v*1.06/1000)*1000)}`;

   sellNext(3);

  }

  function val(id){return document.getElementById(id).value;}

  

  let SELL_REQUESTS = JSON.parse(localStorage.getItem('reown_sell_reqs')||'[]');

  function submitSell(){

   const n=val("sName");

   const req = {

    id: Date.now(),

    name: n || "Unknown",

    phone: val("sPhone") || "N/A",

    model: val("sModel"),

    year: val("sYear"),

    km: val("sKm"),

    cond: val("sCond"),

    estimate: document.getElementById("estValue").textContent,

    photos: [...sellPhotos],

    status: "new",

    date: new Date().toISOString()

   };

   SELL_REQUESTS.unshift(req);

   localStorage.setItem('reown_sell_reqs', JSON.stringify(SELL_REQUESTS));

   showToast((n?n.split(" ")[0]+", your":"Your")+" estimate is locked ��   we'll call within 2 hours");

   sellNext(1);

   window.scrollTo({top:document.getElementById("sell").offsetTop-80,behavior:"smooth"});

  }

  

  let BOOKING_REQUESTS = JSON.parse(localStorage.getItem('reown_book_reqs')||'[]');

  

  function submitBooking(){

   const bBikeId = val("bookBike");

   const bBike = BIKES.find(x => x.id == bBikeId) || {};

   const req = {

    id: Date.now(),

    bikeName: `${bBike.name} ${bBike.variant} (${bBike.reg})`,

    date: val("bookDate"),

    time: val("bookTime"),

    name: val("bookName") || "Unknown",

    phone: val("bookPhone") || "N/A",

    status: "new",

    submittedOn: new Date().toISOString()

   };

   BOOKING_REQUESTS.unshift(req);

   localStorage.setItem('reown_book_reqs', JSON.stringify(BOOKING_REQUESTS));

   document.getElementById('bookOv').classList.remove('open');

   showToast('Test ride booked ��   we\\'ll confirm on WhatsApp');

  }

  

  function openStaffDashboard(){

   document.getElementById("staffDashOv").classList.add("open");

   switchDashTab('sell');

  }

  

  function switchDashTab(tab){

   const tSell = document.getElementById("tabSell");

   const tBook = document.getElementById("tabBook");

   const bSell = document.getElementById("sellReqBody");

   const bBook = document.getElementById("bookReqBody");

   if(tab === 'sell'){

    tSell.style.color = "var(--gold)"; tBook.style.color = "var(--ink3)";

    bSell.style.display = "block"; bBook.style.display = "none";

    renderSellRequests();

   } else {

    tSell.style.color = "var(--ink3)"; tBook.style.color = "var(--gold)";

    bSell.style.display = "none"; bBook.style.display = "block";

    renderBookings();

   }

  }

  

  function updateSellReqStatus(id, st){

   const r = SELL_REQUESTS.find(x => x.id === id);

   if(r){ r.status = st; localStorage.setItem('reown_sell_reqs', JSON.stringify(SELL_REQUESTS)); renderSellRequests(); 

}

  }

  function updateBookReqStatus(id, st){

   const r = BOOKING_REQUESTS.find(x => x.id === id);

   if(r){ r.status = st; localStorage.setItem('reown_book_reqs', JSON.stringify(BOOKING_REQUESTS)); renderBookings(); }

  }

  

  function renderBookings(){

   const body = document.getElementById("bookReqBody");

   if(BOOKING_REQUESTS.length===0){

    body.innerHTML = "<div style='color:var(--ink3);text-align:center;padding:40px;'>No booking requests yet.</div>"; 

return;

   }

   body.innerHTML = BOOKING_REQUESTS.map(r => `

    <div style="background:#f9f9f9;border-radius:var(--radius);padding:20px;border:1px solid 

var(--line);margin-bottom:16px;">

     <div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:12px;">

      <div>

       <h3 style="margin:0;">${r.name} �� <a href="tel:${r.phone}" 

style="color:var(--gold);text-decoration:none;">${r.phone}</a></h3>

       <div style="color:var(--ink3);font-size:14px;margin-top:6px;"><b>${r.bikeName}</b></div>

       <div style="font-weight:700;color:var(--mustard-dark);margin-top:6px;">Schedule: ${r.date} at ${r.time}</div>

      </div>

      <div style="text-align:right;">

       <div style="font-size:12px;color:var(--ink3);margin-bottom:12px;">${new 

Date(r.submittedOn).toLocaleString()}</div>

       ${r.status==='new' ? `<button class="btn btn-sm btn-dark" onclick="updateBookReqStatus(${r.id}, 

'contacted')">Mark Contacted</button>` : 

         r.status==='contacted' ? `<span style="display:inline-block;padding:4px 8px;background:var(--mustard-bg);color

:var(--mustard-dark);border-radius:4px;font-size:12px;font-weight:600;">Contacted</span> <button class="btn btn-sm 

btn-light" style="margin-left:8px;" onclick="updateBookReqStatus(${r.id}, 'closed')">Close</button>` : 

         `<span style="color:var(--green);font-weight:700;font-size:13px;">�S  Closed</span>`}

      </div>

     </div>

    </div>

   `).join('');

  }

  

  function renderSellRequests(){

   const body = document.getElementById("sellReqBody");

   if(SELL_REQUESTS.length===0){

    body.innerHTML = "<div style='color:var(--ink3);text-align:center;padding:40px;'>No sell requests yet.</div>"; 

return;

   }

   body.innerHTML = SELL_REQUESTS.map(r => `

    <div style="background:#f9f9f9;border-radius:var(--radius);padding:20px;border:1px solid 

var(--line);margin-bottom:16px;">

     <div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:12px;">

      <div>

       <h3 style="margin:0;">${r.name} �� <a href="tel:${r.phone}" 

style="color:var(--gold);text-decoration:none;">${r.phone}</a></h3>

       <div style="color:var(--ink3);font-size:14px;margin-top:6px;"><b>${r.model}</b> (${r.year}) �� ${r.km} �� 

${r.cond}</div>

       <div style="font-weight:700;color:var(--green);margin-top:6px;">Est: ${r.estimate}</div>

      </div>

      <div style="text-align:right;">

       <div style="font-size:12px;color:var(--ink3);margin-bottom:12px;">${new Date(r.date).toLocaleString()}</div>

       ${r.status==='new' ? `<button class="btn btn-sm btn-dark" onclick="updateSellReqStatus(${r.id}, 

'contacted')">Mark Contacted</button>` : 

         r.status==='contacted' ? `<span style="display:inline-block;padding:4px 8px;background:var(--mustard-bg);color

:var(--mustard-dark);border-radius:4px;font-size:12px;font-weight:600;">Contacted</span> <button class="btn btn-sm 

btn-light" style="margin-left:8px;" onclick="updateSellReqStatus(${r.id}, 'closed')">Close</button>` : 

         `<span style="color:var(--green);font-weight:700;font-size:13px;">�S  Closed</span>`}

      </div>

     </div>

     ${r.photos.length > 0 ? `

     <div style="display:flex;gap:8px;margin-top:16px;overflow-x:auto;">

      ${r.photos.map(p => `<a href="${p}" target="_blank"><img src="${p}" 

style="height:80px;border-radius:4px;object-fit:cover;width:100px;border:1px solid var(--line);"/></a>`).join('')}

     </div>` : '<div style="margin-top:12px;font-size:13px;color:var(--ink3);">No photos provided.</div>'}

    </div>

   `).join('');

  }

  

  function formatReg(el) {

   let v = el.value.toUpperCase().replace(/[^A-Z0-9]/g, '');

   let res = '';

   if (v.length > 0) res += v.slice(0, 2);

   if (v.length > 2) res += ' ' + v.slice(2, 4);

   if (v.length > 4) res += ' ' + v.slice(4, 6);

   if (v.length > 6) res += ' ' + v.slice(6, 10);

   el.value = res;

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � MISC �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function go(id,el){

   document.getElementById(id).scrollIntoView({behavior:"smooth"});

   if(el){document.querySelectorAll(".nav-item").forEach(n=>n.classList.remove("on"));el.classList.add("on");}

  }

  let toastT;

  function showToast(msg){

   document.getElementById("toastMsg").textContent=msg;

   const t=document.getElementById("toast");

   t.classList.add("show");

   clearTimeout(toastT);

   toastT=setTimeout(()=>t.classList.remove("show"),3500);

  }

  

  renderGrid();

  

  

  

  

  

  function playVid(i){

   const md=media[curId];

   const st=document.getElementById("stage");

   st.innerHTML=`<video src="${md.videos[i]}" controls autoplay playsinline 

style="width:100%;height:100%;object-fit:contain;background:#000;"></video>`;

  }

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � REOWN PDP FEATURES �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function calcEmi(price){

   const dp=Number(document.getElementById("dpSlider").value);

   const ten=Number(document.getElementById("tenSlider").value);

   const rate=Number(document.getElementById("rateSlider").value);

   document.getElementById("dpLabel").textContent=dp+"% ("+fmt(Math.round(price*dp/100))+")";

   document.getElementById("tenLabel").textContent=ten+" months";

   document.getElementById("rateLabel").textContent=rate+"% p.a.";

   const P=price*(1-dp/100), r=rate/1200;

   const e=Math.round(P*r*Math.pow(1+r,ten)/(Math.pow(1+r,ten)-1));

   document.getElementById("emiNum").innerHTML=fmt(e)+'<span 

style="font-size:14px;font-weight:600;color:var(--ink3);">/mo</span>';

   document.getElementById("emiBreak").textContent="Loan "+fmt(Math.round(P))+" | Total interest 

"+fmt(Math.round(e*ten-P));

  }

  function toggleShortlist(id){

   const b=BIKES.find(x=>x.id===id);

   b.hearted=!b.hearted;

   b.shortlisted+=b.hearted?1:-1;

   const h=document.getElementById("heartBtn"),c=document.getElementById("shortCount");

   if(h)h.textContent=b.hearted?"������":"�x��";

   if(c)c.textContent=b.shortlisted+" people have shortlisted this bike";

   showToast(b.hearted?"Added to your shortlist":"Removed from shortlist");

  }

  

  

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � WORKFLOW: ADD / APPROVE / EDIT / DELETE �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  const MODEL_DEFAULTS={

   "Classic 350":{cc:350,power:"20.2 bhp",type:"Cruiser",hue:"#2E5C43",hue2:"#C9A84C",newPrice:240000,newRef:"Classic 

350"},

   "Bullet 350":{cc:350,power:"19.1 bhp",type:"Classic",hue:"#141414",hue2:"#C9A84C",newPrice:210000,newRef:"Bullet 

350"},

   "Hunter 350":{cc:350,power:"20.2 bhp",type:"Roadster",hue:"#191919",hue2:"#C8102E",newPrice:177000,newRef:"Hunter 

350"},

   "Meteor 350":{cc:350,power:"20.2 bhp",type:"Tourer",hue:"#6E3F23",hue2:"#D8A868",newPrice:260000,newRef:"Meteor 

350"},

   "Scram 411":{cc:411,power:"24.3 bhp",type:"Scrambler",hue:"#E8B400",hue2:"#2b2b2e",newPrice:270000,newRef:"Scram 

440"},

   "Himalayan":{cc:411,power:"24.3 

bhp",type:"Adventure",hue:"#3E7CB8",hue2:"#1c3a58",newPrice:390000,newRef:"Himalayan 450"},

   "Interceptor 650":{cc:650,power:"47 

bhp",type:"Roadster",hue:"#55565a",hue2:"#1b1b1d",newPrice:425000,newRef:"Interceptor 650"},

   "Continental GT 650":{cc:650,power:"47 bhp",type:"Caf�� 

Racer",hue:"#B01E28",hue2:"#F2E6C8",newPrice:450000,newRef:"Continental GT 650"},

  };

  function openAddBike(){

   document.getElementById("addOv").classList.add("open");

  }

  function submitBike(){

   const g=id=>document.getElementById(id).value;

   const model=g("abModel"),variant=g("abVariant")||"Standard",reg=g("abReg").toUpperCase()||"KA00XX0000";

   const yr=Number(g("abYear")),km=g("abKm")||"��  ",price=Number(g("abPrice"))||100000;

   const d=MODEL_DEFAULTS[model]||MODEL_DEFAULTS["Classic 350"];

   const id=Math.max(...BIKES.map(b=>b.id))+1;

   BIKES.push({id,km:km+(/km/i.test(km)?"":" km"),owner:g("abOwner"),insValid:g("abIns")||"��  ",

    shortlisted:2,year:yr,name:model,variant,div:"Bengaluru",reg,

    cc:d.cc,asking:price,market:Math.round(price*1.15),newPrice:d.newPrice,newRef:d.newRef,

    hue:d.hue,hue2:d.hue2,type:d.type,power:d.power,

    approval:can.approve()?"approved":"pending",addedBy:role,acc:(g("abAcc")||"").split(",").map(s=>s.trim()).filter(Bo

olean)});

   media[id]={gallery:[],spin:[],videos:[]};

   logEvt("Added motorcycle",model+" "+variant+" ("+reg+")"+(can.approve()?"":" ��   pending"));

   document.getElementById("addOv").classList.remove("open");

   renderGrid();

   showToast(can.approve()?"Motorcycle published to showroom":"Submitted ��   waiting for Manager approval");

  }

  function approveBike(id){

   const b=BIKES.find(x=>x.id===id);

   b.approval="approved";

   logEvt("Approved listing",b.name+" ("+b.reg+")");

   renderGrid();showToast(b.name+" approved & live");

  }

  function denyBike(id){

   const b=BIKES.find(x=>x.id===id);

   b.approval="denied";

   logEvt("Denied listing",b.name+" ("+b.reg+")");

   renderGrid();showToast(b.name+" denied");

  }

  function deleteBike(id){

   const b=BIKES.find(x=>x.id===id);

   if(!confirm("Delete "+b.name+" "+b.variant+" ("+b.reg+") permanently?"))return;

   BIKES.splice(BIKES.indexOf(b),1);

   logEvt("Deleted listing",b.name+" ("+b.reg+")");

   renderGrid();showToast("Listing deleted");

  }

  function editPrice(id){

   const b=BIKES.find(x=>x.id===id);

   const v=prompt("New asking price for "+b.name+" ("+b.reg+"):",b.asking);

   if(v===null)return;

   const old=b.asking;b.asking=Number(v)||b.asking;

   logEvt("Changed price",b.name+": "+fmt(old)+" �    "+fmt(b.asking));

   renderGrid();showToast("Price updated to "+fmt(b.asking));

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � DIRECTOR DASHBOARD �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function openMonitor(){

   const d=document.getElementById("monBody");

   const logins=activity.filter(a=>a.action==="Login").length;

   const views=activity.filter(a=>a.action==="Viewed bike").length;

   const uploads=activity.filter(a=>a.action.includes("Upload")||a.action.includes("photo")).length;

   const adds=activity.filter(a=>a.action==="Added motorcycle").length;

   const appr=activity.filter(a=>a.action==="Approved listing"||a.action==="Denied listing").length;

   const wa=activity.filter(a=>a.action==="WhatsApp enquiry"||a.action==="Booking opened").length;

   const topViewed=[...BIKES].filter(b=>b.views).sort((a,b)=>(b.views||0)-(a.views||0)).slice(0,5);

   const byRole={};activity.forEach(a=>{byRole[a.role]=(byRole[a.role]||0)+1;});

   d.innerHTML=`

    <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:20px;">

     ${[["Logins",logins],["Bike views",views],["Enquiries",wa],["Bikes 

added",adds],["Approvals/denials",appr],["Total events",activity.length]].map(([l,v])=>`

      <div style="background:#f6f5f0;border-radius:12px;padding:14px;text-align:center;">

       <div style="font-family:'Oswald',sans-serif;font-size:24px;font-weight:700;color:var(--gold);">${v}</div>

       <div style="font-size:10px;font-weight:700;letter-spacing:1.5px;text-transform:uppercase;color:var(--ink3);margi

n-top:2px;">${l}</div>

      </div>`).join("")}

    </div>

    <div class="d-label">Activity by role</div>

    <div style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:20px;">

     ${Object.entries(byRole).map(([r,c])=>`<span 

style="font-size:12px;font-weight:700;background:var(--gold-bg);color:var(--gold-dark);padding:6px 

14px;border-radius:980px;">${r}: ${c} actions</span>`).join("")}

    </div>

    <div class="d-label">Most viewed bikes</div>

    ${topViewed.length?topViewed.map(b=>`

     <div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid 

var(--line);font-size:13.5px;">

      <span><b>${b.name}</b> ${b.variant} �� ${b.reg}</span><b style="color:var(--gold);">${b.views} views</b>

     </div>`).join(""):'<div style="font-size:13px;color:var(--ink3);padding:8px 0;">No bike views yet this 

session.</div>'}

    <div class="d-label" style="margin-top:20px;">Activity log (latest first)</div>

    <div style="max-height:260px;overflow-y:auto;border:1.5px solid var(--line);border-radius:12px;">

     ${[...activity].reverse().map(a=>`

      <div style="display:flex;gap:10px;padding:9px 14px;border-bottom:1px solid 

var(--line);font-size:12.5px;align-items:baseline;">

       <span 

style="color:var(--ink3);white-space:nowrap;font-variant-numeric:tabular-nums;">${a.t.toLocaleTimeString()}</span>

       <b style="color:${a.role==="Director"?"#6a3a8a":a.role==="Manager"?"var(--gold)":a.role==="Executive"?"var(--gre

en)":"var(--ink3)"};white-space:nowrap;">${a.role}</b>

       <span><b>${a.action}</b>${a.detail?" ��   "+a.detail:""}</span>

      </div>`).join("")}

    </div>`;

   document.getElementById("monOv").classList.add("open");

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � DELIVERY WALL �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  const deliveries=[

   {img:null,bikeId:12,name:"GT 640 Rocker",sub:"Delivered �� Indiranagar �� \u2605\u2605\u2605\u2605\u2605"},

   {img:null,bikeId:11,name:"Interceptor 650",sub:"Delivered in 100 mins �� Whitefield"},

   {img:null,bikeId:1,name:"Classic 350",sub:"First bike! �� Koramangala �� \u2605\u2605\u2605\u2605\u2605"},

   {img:null,bikeId:9,name:"Himalayan",sub:"Ladakh-ready �� HSR Layout"},

   {img:null,bikeId:4,name:"Hunter 350",sub:"Same-day delivery �� JP Nagar"},

   {img:null,bikeId:5,name:"Meteor 350",sub:"Weekend cruiser �� Hebbal �� \u2605\u2605\u2605\u2605\u2605"},

   {img:null,bikeId:2,name:"Scram 411",sub:"Trail time �� Sarjapur"},

   {img:null,bikeId:7,name:"Bullet 350",sub:"The classic choice �� Jayanagar"},

  ];

  function renderDeliveries(){

   const t=document.getElementById("dwallTrack");

   if(!t)return;

   const card=d=>{

    const b=BIKES.find(x=>x.id===d.bikeId)||BIKES[0];

    return `<div class="dcard">

     <div class="dcard-img">${d.img?`<img src="${d.img}"/>`:art(b)}<div class="dcard-tick">\u2713 Delivered</div></div>

     <div class="dcard-cap"><div class="dcard-name">${d.name}</div><div class="dcard-sub">${d.sub}</div></div>

    </div>`;

   };

   const half=deliveries.map(card).join("");

   t.innerHTML=half+half; /* duplicate for seamless loop */

  }

  function addDeliveries(files){

   const imgs=[...files].filter(f=>f.type.startsWith("image/"));

   let n=0;

   imgs.forEach(f=>{

    const r=new FileReader();

    r.onload=e=>{

     deliveries.unshift({img:e.target.result,bikeId:1,name:"Happy Rider",sub:"Delivered �� Bengaluru �� 

\u2605\u2605\u2605\u2605\u2605"});

     n++;

     if(n===imgs.length){renderDeliveries();showToast(n+" delivery photo"+(n>1?"s":"")+" added to the wall");}

    };

    r.readAsDataURL(f);

   });

   document.getElementById("dwallFile").value="";

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � HERO PHOTO (dealer) �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function setHeroPhoto(files){

   if(!files||!files[0])return;

   const r=new FileReader();

   r.onload=e=>{

    const bg=document.getElementById("heroBg");

    bg.style.backgroundImage=`url(${e.target.result})`;

    bg.querySelector(".hero-bike").style.display="none";

    localStorage.setItem("reown_hero", e.target.result);

    showToast("Hero photo updated");

   };

   r.readAsDataURL(files[0]);

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � DEALER STATUS CONTROL �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function renderStPills(b){

   const el=document.getElementById("stPills");

   if(!el)return;

   const s=stat(b);

   el.innerHTML=["available","booked","sold"].map(x=>

    `<button class="st-pill ${s===x?'on-'+x:''}" onclick="setStatus(${b.id},'${x}')">${x==="booked"?"Booked 

(20%)":x}</button>`).join("");

  }

  function setStatus(id,s){

   const b=BIKES.find(x=>x.id===id);

   b.status=s;

   if(s==="booked")b.bookedOn=new Date().toISOString().slice(0,10);

   if(s!=="booked")delete b.bookedOn;

   renderStPills(b);renderGrid();

   showToast(b.name+" marked "+(s==="booked"?"Booked ��   7-day hold started":s.charAt(0).toUpperCase()+s.slice(1)));

  }

  function openRules(bikeId){

   closeDetail();

   document.getElementById("rulesOv").classList.add("open");

   document.getElementById("rulesOv").scrollTop=0;

  }

  

  /* �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � NEW ARRIVALS �" ��" ��" ��" ��" ��" ��" ��" ��" ��" � */

  function daysAgo(d){return Math.max(0,Math.floor((Date.now()-new Date(d))/(864e5)));}

  function isFresh(b){return daysAgo(b.arrived)<=10;}

  function renderArrivals(){

   const row=document.getElementById("arrivalsRow");

   if(!row)return;

   const recent=[...BIKES].filter(b=>stat(b)!=="sold").sort((a,b)=>new Date(b.arrived)-new Date(a.arrived)).slice(0,6);

   row.innerHTML=recent.map(b=>{

    const m=media[b.id];const cover=m.gallery[0]||m.spin[0];const d=daysAgo(b.arrived);

    return `<div class="arr-card" onclick="openDetail(${b.id})">

     <div class="arr-media">

      ${cover?`<img src="${cover}"/>`:art(b)}

      ${isFresh(b)?'<div class="arr-new">New</div>':''}

      ${m.spin.length>1?'<div class="tag-360" style="top:10px;right:10px;">�  � 360��</div>':''}

     </div>

     <div class="arr-body">





Back to Directory �������}�!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz�������������������������������������������������������������������������������� ������w�!1AQaq"2�B���� #3R�br� $4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������������������������������������������������������������������������ ��?��_��+��?��(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(���(�����