const KEY="homeGlowDataV1"; const DEFAULT_ROOMS=[["Kitchen","๐Ÿณ"],["Bathroom","๐Ÿšฟ"],["Bedroom","๐Ÿ›๏ธ"],["Living Room","๐Ÿ›‹๏ธ"],["Laundry","๐Ÿงบ"]]; const DEFAULT_TASKS=[ ["Make the beds","Bedroom"],["Wash dishes","Kitchen"],["Wipe kitchen counters","Kitchen"], ["Clean the bathroom sink","Bathroom"],["Vacuum the living room","Living Room"] ]; let state=JSON.parse(localStorage.getItem(KEY)||"null")||{ rooms:DEFAULT_ROOMS.map(([name,emoji],i)=>({id:"r"+i,name,emoji})), tasks:DEFAULT_TASKS.map(([text,room],i)=>({id:"t"+i,text,room,done:false})) }; let modalMode="task"; function save(){localStorage.setItem(KEY,JSON.stringify(state))} function esc(x){return String(x).replace(/[&<>"']/g,m=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[m]))} function stats(){let total=state.tasks.length,done=state.tasks.filter(x=>x.done).length;return{total,done,pct:total?Math.round(done/total*100):0}} function nav(id){document.querySelectorAll(".page").forEach(x=>x.classList.toggle("active",x.id===id));document.querySelectorAll(".nav button").forEach(x=>x.classList.toggle("active",x.dataset.page===id));render()} function task(t){return ``} function render(){ const s=stats(), rooms=state.rooms; document.getElementById("homeTasks").innerHTML=state.tasks.length?state.tasks.map(task).join(""):`
No tasks yet. Add one below.
`; document.getElementById("allTasks").innerHTML=state.tasks.length?state.tasks.map(task).join(""):`
No tasks yet.
`; document.getElementById("rooms").innerHTML=rooms.length?rooms.map(r=>`
${esc(r.emoji)}${esc(r.name)}${state.tasks.filter(t=>t.roomId===r.id||t.room===r.name).length} tasks
`).join(""):`
No rooms yet.
`; document.getElementById("percent").textContent=s.pct+"%";document.getElementById("fill").style.width=s.pct+"%"; ["pCompleted","pDone"].forEach(id=>{let e=document.getElementById(id);if(e)e.textContent=s.done}); document.getElementById("pRemaining").textContent=s.total-s.done;document.getElementById("pPercent").textContent=s.pct+"%";document.getElementById("pTotal").textContent=s.total;document.getElementById("goalFill").style.width=s.pct+"%"; const sel=document.getElementById("newRoom");sel.innerHTML=rooms.map(r=>``).join(""); } function toggleTask(id){let t=state.tasks.find(x=>x.id===id);if(!t)return;t.done=!t.done;save();render();toast(t.done?"Task complete! โœจ":"Task unchecked")} function roomView(id){let r=state.rooms.find(x=>x.id===id);if(!r)return;nav("tasks");document.getElementById("allTasks").innerHTML=state.tasks.filter(t=>t.roomId===id||t.room===r.name).map(task).join("")||`
No tasks in ${esc(r.name)} yet.
`;toast(r.name)} function openTask(){modalMode="task";document.getElementById("modalTitle").textContent="โœจ Add a cleaning task";document.getElementById("taskForm").style.display="block";document.getElementById("roomForm").style.display="none";document.getElementById("saveModal").textContent="Add Task";document.getElementById("modal").classList.add("open");render();setTimeout(()=>document.getElementById("newTask").focus(),50)} function openRoom(){modalMode="room";document.getElementById("modalTitle").textContent="๐Ÿ  Add a room";document.getElementById("taskForm").style.display="none";document.getElementById("roomForm").style.display="block";document.getElementById("saveModal").textContent="Add Room";document.getElementById("modal").classList.add("open");setTimeout(()=>document.getElementById("roomName").focus(),50)} function closeModal(){document.getElementById("modal").classList.remove("open");document.getElementById("newTask").value="";document.getElementById("roomName").value="";document.getElementById("roomEmoji").value=""} function saveModal(){ if(modalMode==="task"){let text=document.getElementById("newTask").value.trim(),roomId=document.getElementById("newRoom").value;if(!text){toast("Enter a task name");return}let r=state.rooms.find(x=>x.id===roomId);state.tasks.push({id:"t"+Date.now(),text,roomId,room:r?.name||"Other",done:false});save();closeModal();nav("tasks");toast("Task added! โœจ");return} let name=document.getElementById("roomName").value.trim(),emoji=document.getElementById("roomEmoji").value.trim()||"๐Ÿ ";if(!name){toast("Enter a room name");return}if(state.rooms.some(r=>r.name.toLowerCase()===name.toLowerCase())){toast("That room already exists");return} state.rooms.push({id:"r"+Date.now(),name,emoji});save();closeModal();render();toast("Room added! ๐Ÿ ") } function deleteRoom(id){let r=state.rooms.find(x=>x.id===id);if(!r)return;if(!confirm(`Delete ${r.name}? Its tasks will stay under Other.`))return;state.rooms=state.rooms.filter(x=>x.id!==id);state.tasks.forEach(t=>{if(t.roomId===id){t.roomId="";t.room="Other"}});save();render();toast("Room deleted")} function toast(m){let x=document.getElementById("toast");x.textContent=m;x.style.display="block";clearTimeout(window._t);window._t=setTimeout(()=>x.style.display="none",1600)} document.getElementById("app").innerHTML=`

HOME GLOW

Clean home. Clear mind.

Good morning! โœจ

Let's make your home glow.

Today's progress0%

๐Ÿงน Today's Cleaning

๐Ÿ  Rooms

๐Ÿงน All Tasks

๐Ÿ“… Cleaning Schedule

โ˜€๏ธ Daily
Dishes, beds, counters, quick tidy
๐ŸŒฟ Monday
Bathrooms + laundry
๐Ÿงน Wednesday
Vacuum + dust
โœจ Friday
Kitchen deep clean
๐Ÿก Saturday
Whole-home reset
๐ŸŒ™ Monthly
Windows, fridge, fans & extras

โญ Your Progress

Every little task makes your home glow.

Completed
0
Remaining
0
Completion
0%
Total tasks
0

๐ŸŒŸ Cleaning Goal

`; document.querySelectorAll(".nav button").forEach(b=>b.onclick=()=>nav(b.dataset.page)); document.getElementById("date").textContent=new Date().toLocaleDateString(undefined,{weekday:"short",month:"short",day:"numeric"}); document.getElementById("modal").addEventListener("click",e=>{if(e.target.id==="modal")closeModal()}); render(); if("serviceWorker" in navigator) navigator.serviceWorker.register("sw.js").catch(()=>{});