`} ]; function renderApps(filter=''){ appsGrid.innerHTML=''; const filtered = apps.filter(a=>a.label.toLowerCase().includes(filter.toLowerCase())); if(!filtered.length){ appsGrid.innerHTML='

No apps found

'; return; } filtered.forEach(a=>{ const tile=document.createElement('div'); tile.className='app-tile'; tile.tabIndex=0; tile.innerHTML=a.icon+`
${a.label}
`; tile.addEventListener('click',()=>{ openWindow(a); addRecent(a.label); hideMenu(); }); tile.addEventListener('keydown',e=>{ if(e.key==='Enter'||e.key===' '){e.preventDefault();tile.click();} }); appsGrid.append(tile); }); } function addRecent(t){ recent=recent.filter(x=>x!==t); recent.unshift(t); if(recent.length>5) recent.pop(); recentDiv.innerHTML = recent.length ? 'Recent: '+recent.map(x=>`${x}`).join(', ') : 'No recent searches yet.'; } function openWindow(app){ if(document.getElementById('win-'+app.id)){ document.getElementById('win-'+app.id).style.zIndex = ++zIndex; return; } const w=document.createElement('div'); w.id='win-'+app.id; w.className='app-window'; w.style.top='60px'; w.style.left='60px'; w.style.zIndex=++zIndex; w.setAttribute('role','dialog'); w.setAttribute('aria-label',app.label); const tb=document.createElement('div'); tb.className='title-bar'; tb.textContent=app.label; const cb=document.createElement('button'); cb.className='close-btn'; cb.textContent='×'; cb.addEventListener('click',()=>w.remove()); tb.append(cb); w.append(tb); const cnt=document.createElement('div'); cnt.className='content'; cnt.innerHTML=app.content; w.append(cnt); desktop.append(w); drag(w,tb); } function drag(el,h){ let x1=0,y1=0,x2=0,y2=0; h.onpointerdown=e=>{ e.preventDefault(); x2=e.clientX; y2=e.clientY; document.onpointermove=move; document.onpointerup=stop; el.style.cursor='grabbing'; el.style.zIndex=++zIndex; }; function move(e){ e.preventDefault(); x1=x2-e.clientX; y1=y2-e.clientY; x2=e.clientX; y2=e.clientY; let nx=el.offsetLeft-x1, ny=el.offsetTop-y1; const maxX=window.innerWidth-el.offsetWidth, maxY=window.innerHeight-el.offsetHeight-48; if(nx<0) nx=0; if(ny<0) ny=0; if(nx>maxX) nx=maxX; if(ny>maxY) ny=maxY; el.style.left=nx+'px'; el.style.top=ny+'px'; } function stop(){ document.onpointermove=null; document.onpointerup=null; el.style.cursor='grab'; } } function showMenu(){ startMenu.classList.add('visible'); startButton.setAttribute('aria-expanded',true); searchInput.focus(); } function hideMenu(){ startMenu.classList.remove('visible'); startButton.setAttribute('aria-expanded',false); searchInput.value=''; renderApps(); } startButton.addEventListener('click',e=>{ e.stopPropagation(); startMenu.classList.contains('visible') ? hideMenu() : showMenu(); }); startMenu.addEventListener('click',e=>e.stopPropagation()); document.addEventListener('click',hideMenu); document.addEventListener('keydown',e=>{ if(e.key==='Escape'&&startMenu.classList.contains('visible')){ hideMenu(); startButton.focus(); } }); searchInput.addEventListener('input',e=>{ const v=e.target.value.trim(); renderApps(v); if(v) addRecent(v); }); renderApps(); })();