diff --git a/projects/neural-habit-builder/index.html b/projects/neural-habit-builder/index.html new file mode 100644 index 00000000..5001be73 --- /dev/null +++ b/projects/neural-habit-builder/index.html @@ -0,0 +1,53 @@ + + + + + +Neural Habit Builder + + + + + + + +
+
+ +
+ +
+

Neural Habit Builder

+
+Level: 1 +
+
+ +
+ + + +
+
+
+
+ +
+ +
+

Habits

+
+
+ +
+

Weekly Progress

+ +
+ +
+ +
+ + + + diff --git a/projects/neural-habit-builder/script.js b/projects/neural-habit-builder/script.js new file mode 100644 index 00000000..a051c91f --- /dev/null +++ b/projects/neural-habit-builder/script.js @@ -0,0 +1,185 @@ +/* =========================== + STATE +=========================== */ + +let habits = JSON.parse(localStorage.getItem("habits")) || []; +let xp = parseInt(localStorage.getItem("xp")) || 0; +let level = parseInt(localStorage.getItem("level")) || 1; + +const habitList = document.getElementById("habitList"); +const levelDisplay = document.getElementById("level"); +const xpBar = document.getElementById("xpBar"); +const addHabitBtn = document.getElementById("addHabitBtn"); +const habitInput = document.getElementById("habitInput"); + +/* =========================== + ADD HABIT +=========================== */ + +addHabitBtn.addEventListener("click", addHabit); + +function addHabit(){ +const name = habitInput.value.trim(); +if(!name) return; + +habits.push({ +id:Date.now(), +name:name, +streak:0, +completed:false, +history:[] +}); + +habitInput.value=""; +saveData(); +renderHabits(); +} + +/* =========================== + RENDER HABITS +=========================== */ + +function renderHabits(){ +habitList.innerHTML=""; + +habits.forEach(habit=>{ +const div = document.createElement("div"); +div.className="habit"+(habit.completed?" completed":""); + +const span = document.createElement("span"); +span.textContent=`${habit.name} | 🔥 ${habit.streak}`; + +const completeBtn = document.createElement("button"); +completeBtn.textContent="Complete"; +completeBtn.className="complete-btn"; +completeBtn.onclick=()=>completeHabit(habit.id); + +const deleteBtn = document.createElement("button"); +deleteBtn.textContent="Delete"; +deleteBtn.className="delete-btn"; +deleteBtn.onclick=()=>deleteHabit(habit.id); + +div.appendChild(span); +div.appendChild(completeBtn); +div.appendChild(deleteBtn); + +habitList.appendChild(div); +}); + +updateXPUI(); +drawChart(); +} + +/* =========================== + COMPLETE HABIT +=========================== */ + +function completeHabit(id){ +const today = new Date().toDateString(); + +habits = habits.map(habit=>{ +if(habit.id===id && !habit.completed){ +habit.completed=true; +habit.streak++; +habit.history.push({date:today}); +xp+=10; +checkLevelUp(); +} +return habit; +}); + +saveData(); +renderHabits(); +} + +/* =========================== + DELETE HABIT +=========================== */ + +function deleteHabit(id){ +habits = habits.filter(h=>h.id!==id); +saveData(); +renderHabits(); +} + +/* =========================== + XP SYSTEM +=========================== */ + +function checkLevelUp(){ +const required = level*100; +if(xp>=required){ +xp-=required; +level++; +} +} + +function updateXPUI(){ +levelDisplay.textContent=level; +const required = level*100; +const percent = (xp/required)*100; +xpBar.style.width=percent+"%"; +} + +/* =========================== + CHART +=========================== */ + +function drawChart(){ +const canvas=document.getElementById("chart"); +const ctx=canvas.getContext("2d"); +ctx.clearRect(0,0,canvas.width,canvas.height); + +let data={}; + +habits.forEach(h=>{ +h.history.forEach(entry=>{ +data[entry.date]=(data[entry.date]||0)+1; +}); +}); + +const labels=Object.keys(data).slice(-7); +const values=labels.map(l=>data[l]); + +const max=Math.max(...values,5); +const barWidth=canvas.width/(labels.length*2); + +labels.forEach((label,i)=>{ +const height=(values[i]/max)*150; +ctx.fillStyle="#6c63ff"; +ctx.fillRect(i*barWidth*2+20,180-height,barWidth,height); +}); +} + +/* =========================== + DAILY RESET +=========================== */ + +function resetDaily(){ +const today = new Date().toDateString(); +habits.forEach(habit=>{ +if(habit.history.length>0){ +const last=habit.history[habit.history.length-1].date; +if(last!==today){ +habit.completed=false; +} +} +}); +} + +/* =========================== + STORAGE +=========================== */ + +function saveData(){ +localStorage.setItem("habits",JSON.stringify(habits)); +localStorage.setItem("xp",xp); +localStorage.setItem("level",level); +} + +/* =========================== + INIT +=========================== */ + +resetDaily(); +renderHabits(); diff --git a/projects/neural-habit-builder/style.css b/projects/neural-habit-builder/style.css new file mode 100644 index 00000000..2c421108 --- /dev/null +++ b/projects/neural-habit-builder/style.css @@ -0,0 +1,199 @@ +/* =========================== + GLOBAL RESET +=========================== */ + +*{ +margin:0; +padding:0; +box-sizing:border-box; +} + +body{ +font-family:'Poppins',sans-serif; +background:#f4f7ff; +overflow-x:hidden; +color:#222; +} + +/* =========================== + ANIMATED BACKGROUND BLOBS +=========================== */ + +.blob{ +position:fixed; +width:400px; +height:400px; +background:linear-gradient(135deg,#6c63ff,#00c6ff); +border-radius:50%; +filter:blur(120px); +opacity:0.4; +animation:moveBlob 20s infinite alternate; +z-index:-1; +} + +.blob2{ +right:-150px; +bottom:-150px; +animation-duration:25s; +} + +@keyframes moveBlob{ +0%{transform:translate(0,0);} +100%{transform:translate(100px,-100px);} +} + +/* =========================== + LAYOUT +=========================== */ + +.container{ +width:95%; +max-width:1200px; +margin:40px auto; +} + +.header{ +display:flex; +justify-content:space-between; +align-items:center; +margin-bottom:30px; +} + +h1{ +font-family:'Space Grotesk',sans-serif; +font-size:2rem; +} + +h2{ +font-family:'Space Grotesk',sans-serif; +margin-bottom:15px; +} + +/* =========================== + CARD STYLE (Neumorphism) +=========================== */ + +.card{ +background:#f4f7ff; +border-radius:20px; +padding:25px; +box-shadow:8px 8px 16px #d1d9ff,-8px -8px 16px #ffffff; +margin-bottom:20px; +} + +/* =========================== + INPUT SECTION +=========================== */ + +input{ +padding:12px; +border-radius:10px; +border:none; +outline:none; +width:70%; +margin-right:10px; +box-shadow:inset 4px 4px 8px #d1d9ff, +inset -4px -4px 8px #ffffff; +} + +button{ +padding:12px 20px; +border:none; +border-radius:10px; +cursor:pointer; +font-weight:600; +transition:0.3s; +background:linear-gradient(135deg,#6c63ff,#00c6ff); +color:white; +} + +button:hover{ +transform:scale(1.05); +} + +/* =========================== + HABIT LIST +=========================== */ + +.habit{ +display:flex; +justify-content:space-between; +align-items:center; +padding:15px; +margin-bottom:10px; +border-radius:15px; +background:white; +box-shadow:4px 4px 8px #d1d9ff,-4px -4px 8px #ffffff; +transition:0.3s; +} + +.habit.completed{ +background:#e0f7ff; +} + +.habit span{ +font-weight:500; +} + +.complete-btn{ +background:#00c851; +} + +.delete-btn{ +background:#ff4444; +margin-left:10px; +} + +/* =========================== + XP BAR +=========================== */ + +.xp-container{ +margin-top:15px; +height:20px; +background:#e0e7ff; +border-radius:10px; +overflow:hidden; +} + +.xp-bar{ +height:100%; +width:0%; +background:linear-gradient(90deg,#6c63ff,#00c6ff); +transition:0.5s; +} + +/* =========================== + GRID +=========================== */ + +.grid{ +display:grid; +grid-template-columns:repeat(auto-fit,minmax(300px,1fr)); +gap:20px; +} + +/* =========================== + CANVAS +=========================== */ + +canvas{ +margin-top:20px; +width:100% !important; +height:200px !important; +} + +/* =========================== + RESPONSIVE +=========================== */ + +@media(max-width:600px){ +.header{ +flex-direction:column; +gap:10px; +} +input{ +width:100%; +margin-bottom:10px; +} +}