diff --git a/dashboard-euclideans.html b/dashboard-euclideans.html
index 7e302392..e6b3e87a 100644
--- a/dashboard-euclideans.html
+++ b/dashboard-euclideans.html
@@ -359,8 +359,10 @@
@@ -1122,6 +1218,344 @@
Silve
// Boot
loadAPI();
+
+ const VIBE_MILESTONES = [
+ { label: "Vibe Phase 1", required: 25, deadline: "2026-01-22" },
+ { label: "Vibe Phase 2", required: 50, deadline: "2026-01-29" },
+ { label: "Vibe Phase 3", required: 75, deadline: "2026-02-05" },
+ { label: "Vibe Phase 4", required: 100, deadline: "2026-02-12" }
+];
+
+// ========= DAILY VIBE RULE =========
+const VIBE_START_DATE = new Date("2026-01-14"); // first day of vibe
+const DAILY_VIBE_REQUIRED = 3.33;
+
+const CS_MILESTONES = [
+ { label: "CS Week 1", cumulative: 6, deadline: "2026-02-12" },
+ { label: "CS Week 2", cumulative: 18, deadline: "2026-02-19" },
+ { label: "CS Week 3", cumulative: 30, deadline: "2026-02-26" },
+ { label: "CS Week 4", cumulative: 42, deadline: "2026-03-05" }
+];
+
+function setEmail() {
+ const email = document.getElementById("emailInput").value.trim();
+
+ if (!email) {
+ alert("Please enter your email");
+ return;
+ }
+
+ localStorage.setItem("userEmail", email);
+ renderMyDashboard();
+}
+
+function getMyData() {
+ const email = localStorage.getItem("userEmail");
+ if (!email || !apiData || !apiData.dashboard) return null;
+
+ return apiData.dashboard.find(
+ r => r.Email && r.Email.toLowerCase() === email.toLowerCase()
+ );
+}
+
+function renderMyDashboard() {
+ const me = getMyData();
+
+ if (!me) {
+ document.getElementById("my-rank").textContent = "Not found";
+ return;
+ }
+
+ document.getElementById("my-rank").textContent = me.Rank;
+ document.getElementById("my-cs").textContent = me["Case Study Progress"];
+ document.getElementById("my-vibe").textContent = me["Vibe Progress"];
+ document.getElementById("my-hp").textContent = me["Health Points"];
+ document.getElementById("my-overall").textContent = me["Overall Progress"];
+
+ console.log("Rendering vibe milestones");
+ renderMyVibe();
+ renderMyCS();
+ renderMyHPStatus();
+ renderNextDeadline();
+}
+
+function getMyVibeProgress() {
+ const email = localStorage.getItem("userEmail");
+ if (!email || !apiData || !apiData.dashboard) return 0;
+
+ const row = apiData.dashboard.find(
+ r => r.Email && r.Email.toLowerCase() === email.toLowerCase()
+ );
+
+ return row ? Number(row["Vibe Progress"]) : 0;
+}
+
+function getExpectedVibeProgressToday() {
+ const today = new Date();
+ const daysPassed = Math.floor(
+ (today - VIBE_START_DATE) / (1000 * 60 * 60 * 24)
+ );
+
+ if (daysPassed <= 0) return 0;
+
+ return Math.min(100, daysPassed * DAILY_VIBE_REQUIRED);
+}
+
+function getDailyVibeCheck() {
+ const actual = getMyVibeProgress();
+ const expected = getExpectedVibeProgressToday();
+
+ if (actual >= expected) {
+ return {
+ onTrack: true,
+ message: `📈 Daily Vibe: On track (${actual.toFixed(1)}% ≥ ${expected.toFixed(1)}%)`
+ };
+ }
+
+ const deficit = (expected - actual).toFixed(1);
+
+ return {
+ onTrack: false,
+ message: `⚠️ Daily Vibe lagging by ${deficit}% (Expected ${expected.toFixed(1)}%)`
+ };
+}
+
+
+function computeVibeStatus() {
+ const current = getMyVibeProgress();
+ const now = new Date();
+
+ return VIBE_MILESTONES.map(m => ({
+ ...m,
+ current,
+ completed: current >= m.required,
+ isLate: now > new Date(m.deadline) && current < m.required
+ }));
+}
+
+function renderMyVibe() {
+ const container = document.getElementById("my-vibe-section");
+ const vibeData = computeVibeStatus();
+
+ container.innerHTML = vibeData.map(v => {
+ const shown = Math.min(v.current, v.required);
+
+ let status =
+ v.completed ? "✅ Completed"
+ : v.isLate ? "❌ Missed deadline"
+ : "⚠️ In progress";
+
+ return `
+
+ ${v.label} — ${shown}% / ${v.required}%
+ | ${status}
+ | Deadline: ${v.deadline}
+
+ `;
+ }).join("");
+}
+
+function getMyCSCount() {
+ const email = localStorage.getItem("userEmail");
+ if (!email || !apiData || !apiData.csProgress) return 0;
+
+ const row = apiData.csProgress.find(
+ r => r.Email && r.Email.toLowerCase() === email.toLowerCase()
+ );
+
+ if (!row) return 0;
+
+ let count = 0;
+
+ Object.keys(row).forEach(key => {
+ if (
+ key.includes("_CS") &&
+ !key.toLowerCase().includes("progress")
+ ) {
+ const val = row[key];
+
+ if (val === "Yes" || val === "✓" || val === true) {
+ count++;
+ }
+ }
+ });
+
+ return count;
+}
+
+function computeCSStatus() {
+ const submitted = getMyCSCount();
+ const now = new Date();
+
+ return CS_MILESTONES.map(m => {
+ const required = Number(m.cumulative);
+ const shown = Math.min(submitted, required);
+
+ return {
+ label: m.label,
+ submitted: shown,
+ required,
+ completed: submitted >= required,
+ isLate: now > new Date(m.deadline) && submitted < required,
+ deadline: m.deadline
+ };
+ });
+}
+
+function renderMyCS() {
+ const container = document.getElementById("my-cs-section");
+ if (!container) return;
+
+ const csData = computeCSStatus();
+
+ container.innerHTML = csData.map(cs => {
+ let status =
+ cs.completed ? "✅ Completed"
+ : cs.isLate ? "❌ Missed deadline"
+ : "⚠️ In progress";
+
+ return `
+
+ ${cs.label} — ${cs.submitted} / ${cs.required} CS
+ | ${status}
+ | Deadline: ${cs.deadline}
+
+ `;
+ }).join("");
+}
+
+function renderMyHPStatus() {
+ const statusEl = document.getElementById("my-hp-status");
+ const actionEl = document.getElementById("my-hp-action");
+
+ if (!statusEl || !actionEl || !hpData) return;
+
+ const email = localStorage.getItem("userEmail");
+ if (!email) return;
+
+ const me = hpData.leaderboard.find(
+ r => r.email && r.email.toLowerCase() === email.toLowerCase()
+ );
+
+ if (!me) return;
+
+ const isSafe = me.status === "SAFE";
+
+ // STATUS PILL
+ statusEl.innerHTML = `
+ HP STATUS: ${me.status}
+ (Current: ${me.currentHP.toFixed(2)} | Base: ${me.baseHP.toFixed(2)})
+ `;
+
+ statusEl.style.background = isSafe ? "#C8E6C9" : "#FFCDD2";
+ statusEl.style.color = isSafe ? "#1B5E20" : "#B71C1C";
+
+ // ACTION GUIDANCE
+ actionEl.style.display = "block";
+
+ const vibeStatus = computeVibeStatus();
+const csStatus = computeCSStatus();
+
+// find first pending / missed items
+const pendingVibe = vibeStatus.find(v => !v.completed);
+const pendingCS = csStatus.find(c => !c.completed);
+
+let messages = [];
+// DAILY VIBE CHECK
+const dailyVibe = getDailyVibeCheck();
+messages.push(dailyVibe.message);
+
+
+if (pendingVibe) {
+ if (pendingVibe.isLate) {
+ messages.push(`❌ Missed ${pendingVibe.label} deadline`);
+ } else {
+ messages.push(`⏳ ${pendingVibe.label} in progress`);
+ }
+}
+
+if (pendingCS) {
+ if (pendingCS.isLate) {
+ messages.push(`❌ ${pendingCS.label} missed`);
+ } else {
+ messages.push(`⏳ ${pendingCS.label} incomplete (${pendingCS.submitted}/${pendingCS.required})`);
+ }
+}
+
+if (isSafe) {
+ actionEl.style.background = "#E8F5E9";
+ actionEl.style.color = "#1B5E20";
+ actionEl.innerHTML = `
+ ✅ You are SAFE.
+ ${messages.length ? messages.join("
") : "All milestones on track."}
+ `;
+} else {
+ actionEl.style.background = "#FDECEA";
+ actionEl.style.color = "#B71C1C";
+ actionEl.innerHTML = `
+ ⚠️ You are UNSAFE. Focus areas:
+ ${messages.join("
")}
+
👉 Priority: Complete the earliest pending milestone.
+ `;
+ }
+}
+
+function renderNextDeadline() {
+ const el = document.getElementById("my-next-deadline");
+ if (!el) return;
+
+ const vibe = computeVibeStatus();
+ const cs = computeCSStatus();
+
+ const pending = [...vibe, ...cs]
+ .filter(m => !m.completed)
+ .sort((a, b) => new Date(a.deadline) - new Date(b.deadline));
+
+
+ if (!pending.length) {
+ el.textContent = "No upcoming deadlines. You’re all caught up!";
+ el.style.background = "#E8F5E9";
+ el.style.color = "#1B5E20";
+ return;
+ }
+
+ const next = pending[0];
+ const daysLeft = Math.ceil(
+ (new Date(next.deadline) - new Date()) / (1000 * 60 * 60 * 24)
+ );
+
+ el.textContent = `⏰ Next Deadline: ${next.label} — ${next.deadline} (${daysLeft} days left)`;
+
+ if (daysLeft <= 0) {
+ el.style.background = "#FFCDD2";
+ el.style.color = "#B71C1C";
+ } else if (daysLeft <= 3) {
+ el.style.background = "#FFF3CD";
+ el.style.color = "#856404";
+ } else {
+ el.style.background = "#E3F2FD";
+ el.style.color = "#0D47A1";
+ }
+}
+
+document.getElementById("view-my-cs")?.addEventListener("click", () => {
+ const email = localStorage.getItem("userEmail");
+ if (!email) return;
+
+ // switch to CS tab
+ activateTopTab("cs");
+
+ // wait for CS tab to render
+ setTimeout(() => {
+ const search = document.getElementById("cs-search");
+ if (!search) return;
+
+ search.value = email;
+ search.dispatchEvent(new Event("input", { bubbles: true }));
+ search.focus();
+ }, 300);
+});
+