diff --git a/src/static/script.js b/src/static/script.js
index 1044193e..7fff2c05 100644
--- a/src/static/script.js
+++ b/src/static/script.js
@@ -1,3 +1,1098 @@
+// // DevPath client-side behavior.
+// // Compatibility key for bookmarks.js: "devpathSavedProjects"
+
+// (function () {
+// var html = document.documentElement;
+
+// function applyTheme(theme) {
+// var isDark = theme === "dark";
+// html.setAttribute("data-theme", theme);
+// try {
+// localStorage.setItem("theme", theme);
+// } catch (err) {
+// // Storage can be unavailable in private browsing.
+// }
+
+// document.querySelectorAll(".theme-toggle").forEach(function (button) {
+// button.setAttribute("aria-pressed", isDark ? "true" : "false");
+// button.setAttribute("aria-label", isDark ? "Switch to light mode" : "Switch to dark mode");
+// });
+
+// // Sync preview cards active styles
+// var cards = document.querySelectorAll(".theme-preview-card");
+// cards.forEach(function (card) {
+// if (card.getAttribute("data-theme-target") === theme) {
+// card.style.borderColor = "var(--accent)";
+// } else {
+// card.style.borderColor = "var(--border)";
+// }
+// });
+// }
+
+// function initTheme() {
+// var theme = "light";
+
+// try {
+// theme = localStorage.getItem("theme") || html.getAttribute("data-theme") || "light";
+// } catch (err) {
+// theme = html.getAttribute("data-theme") || "light";
+// }
+
+// applyTheme(theme);
+
+// requestAnimationFrame(function () {
+// html.classList.add("theme-ready");
+// });
+// }
+
+// document.addEventListener("DOMContentLoaded", function () {
+// // Inject the theme modal HTML dynamically
+// var modalHtml = `
+//
+//
+//
+//
+//
+//
+
+//
+//
+//
+//
+//
+// `;
+// document.body.insertAdjacentHTML("beforeend", modalHtml);
+
+// var modal = document.getElementById("theme-preview-modal");
+// var closeBtn = document.getElementById("close-theme-modal");
+// var cards = document.querySelectorAll(".theme-preview-card");
+
+// function closeModal() {
+// if (modal) {
+// modal.style.display = "none";
+// modal.setAttribute("aria-hidden", "true");
+// }
+// }
+
+// if (closeBtn) closeBtn.addEventListener("click", closeModal);
+// if (modal) {
+// modal.addEventListener("click", function (e) {
+// if (e.target === modal) closeModal();
+// });
+// }
+
+// cards.forEach(function (card) {
+// card.addEventListener("click", function () {
+// var theme = this.getAttribute("data-theme-target");
+// applyTheme(theme);
+// setTimeout(closeModal, 150);
+// });
+// card.addEventListener("mouseenter", function () {
+// if (this.getAttribute("data-theme-target") !== html.getAttribute("data-theme")) {
+// this.style.borderColor = "var(--gray-400)";
+// }
+// });
+// card.addEventListener("mouseleave", function () {
+// if (this.getAttribute("data-theme-target") !== html.getAttribute("data-theme")) {
+// this.style.borderColor = "var(--border)";
+// }
+// });
+// });
+
+// // Update active styles on modal load
+// var currentTheme = html.getAttribute("data-theme") || "light";
+// cards.forEach(function (card) {
+// if (card.getAttribute("data-theme-target") === currentTheme) {
+// card.style.borderColor = "var(--accent)";
+// } else {
+// card.style.borderColor = "var(--border)";
+// }
+// });
+// });
+
+// document.addEventListener("click", function (event) {
+// var toggle = event.target.closest(".theme-toggle");
+// if (!toggle) return;
+// event.preventDefault();
+// var modal = document.getElementById("theme-preview-modal");
+// if (modal) {
+// modal.style.display = "flex";
+// modal.setAttribute("aria-hidden", "false");
+// }
+// });
+
+// initTheme();
+// })();
+
+// (function initMobileNav() {
+// var toggle = document.getElementById("nav-mobile-toggle");
+// var menu = document.getElementById("nav-mobile-menu");
+// if (!toggle || !menu) return;
+
+// function setOpen(isOpen) {
+// menu.classList.toggle("open", isOpen);
+// toggle.classList.toggle("open", isOpen);
+// toggle.setAttribute("aria-expanded", isOpen ? "true" : "false");
+// }
+
+// toggle.addEventListener("click", function (e) {
+// e.stopPropagation();
+// setOpen(!menu.classList.contains("open"));
+// });
+
+// // Only close menu when clicking actual navigation links, not buttons
+// menu.querySelectorAll(".nav-mobile-link").forEach(function (link) {
+// if (link.tagName.toLowerCase() === "a") {
+// link.addEventListener("click", function () {
+// setOpen(false);
+// });
+// }
+// });
+
+// // Close when clicking outside the menu
+// document.addEventListener("click", function (e) {
+// if (menu.classList.contains("open") &&
+// !menu.contains(e.target) &&
+// !toggle.contains(e.target)) {
+// setOpen(false);
+// }
+// });
+
+// window.addEventListener("resize", function () {
+// if (window.innerWidth >= 640) setOpen(false);
+// });
+// })();
+
+// var POINTS_PER_SEARCH = 5;
+// var POINTS_PER_VIEW = 10;
+// var POINTS_PER_CODE_OPEN = 15;
+// var POINTS_PER_COMPLETION = 30;
+
+// var PROGRESS_TARGET_SEARCHES = 10;
+// var PROGRESS_TARGET_VIEWS = 10;
+// var PROGRESS_TARGET_CODE_OPENS = 10;
+// var PROGRESS_TARGET_COMPLETIONS = 5;
+
+// var PROGRESS_MAX_POINTS = (
+// PROGRESS_TARGET_SEARCHES * POINTS_PER_SEARCH +
+// PROGRESS_TARGET_VIEWS * POINTS_PER_VIEW +
+// PROGRESS_TARGET_CODE_OPENS * POINTS_PER_CODE_OPEN +
+// PROGRESS_TARGET_COMPLETIONS * POINTS_PER_COMPLETION
+// );
+
+// var STORAGE_KEY = "devpathUserProgress";
+// var progress = {
+// searches: 0,
+// projectViews: 0,
+// codeOpens: 0,
+// completions: 0,
+// points: 0,
+// viewedProjects: [],
+// completedProjects: [],
+// achievements: [],
+// badges: {
+// first_search: false,
+// project_explorer: false,
+// code_starter: false,
+// completionist: false,
+// roadmap_runner: false
+// },
+// bestScore: 0
+// };
+
+// function loadProgressState() {
+// try {
+// var saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || "null");
+// if (!saved || typeof saved !== "object") return;
+// progress = Object.assign(progress, saved);
+// progress.viewedProjects = Array.isArray(saved.viewedProjects) ? saved.viewedProjects : [];
+// progress.completedProjects = Array.isArray(saved.completedProjects) ? saved.completedProjects : [];
+// progress.achievements = Array.isArray(saved.achievements) ? saved.achievements : [];
+// progress.badges = Object.assign(progress.badges, saved.badges || {});
+// } catch (err) {
+// console.warn("Unable to load progress state", err);
+// }
+// }
+
+// function saveProgressState() {
+// try {
+// progress.bestScore = Math.max(progress.bestScore || 0, progress.points || 0);
+// localStorage.setItem(STORAGE_KEY, JSON.stringify(progress));
+// } catch (err) {
+// console.warn("Unable to save progress state", err);
+// }
+// }
+
+// function computeProgressPoints() {
+// progress.points = progress.searches * POINTS_PER_SEARCH + progress.projectViews * POINTS_PER_VIEW +
+// progress.codeOpens * POINTS_PER_CODE_OPEN + progress.completions * POINTS_PER_COMPLETION;
+// }
+
+// function showAchievementToast(title, detail) {
+// var toast = document.getElementById("achievement-toast");
+// if (!toast) return;
+// toast.textContent = "";
+// var strong = document.createElement("strong");
+// strong.textContent = title;
+// var span = document.createElement("span");
+// span.textContent = detail;
+// toast.appendChild(strong);
+// toast.appendChild(span);
+// toast.classList.add("show");
+// window.clearTimeout(showAchievementToast.timeout);
+// showAchievementToast.timeout = window.setTimeout(function () {
+// toast.classList.remove("show");
+// }, 3200);
+// }
+
+// function addAchievement(title, detail) {
+// if (progress.achievements.some(function (item) { return item.title === title; })) return;
+// progress.achievements.unshift({
+// title: title,
+// description: detail,
+// date: new Date().toLocaleDateString()
+// });
+// progress.achievements = progress.achievements.slice(0, 5);
+// }
+
+// function unlockBadge(id, title, detail) {
+// if (progress.badges[id]) return;
+// progress.badges[id] = true;
+// addAchievement(title, detail);
+// showAchievementToast("Badge unlocked", title + " - " + detail);
+// }
+
+// function tryUnlockBadges() {
+// if (progress.searches >= 1) unlockBadge("first_search", "First Search", "You used DevPath to find your first project.");
+// if (progress.projectViews >= 1) unlockBadge("project_explorer", "Project Explorer", "You viewed a project detail.");
+// if (progress.codeOpens >= 1) unlockBadge("code_starter", "Code Starter", "You opened starter code.");
+// if (progress.completions >= 1) unlockBadge("completionist", "Completionist", "You marked a project complete.");
+// if (progress.searches >= 5) unlockBadge("roadmap_runner", "Roadmap Runner", "You searched five times.");
+// }
+
+// function projectIsCompleted(projectId) {
+// return progress.completedProjects.some(function (item) {
+// return (item && typeof item === "object" ? item.id : item) === projectId;
+// });
+// }
+
+// function updateProfileWidgets() {
+// var pointsEl = document.getElementById("progress-points");
+// var statsEl = document.getElementById("progress-stats");
+// var meterFill = document.getElementById("progress-meter-fill");
+// var badgesEl = document.getElementById("progress-badges");
+// var achievementList = document.getElementById("achievement-list");
+// var leaderboardList = document.getElementById("leaderboard-list");
+// var historyList = document.getElementById("completed-history-list");
+// var completionBtn = document.getElementById("btn-mark-complete");
+
+// if (pointsEl) pointsEl.textContent = progress.points;
+// if (statsEl) {
+// statsEl.innerHTML =
+// "Searches" + progress.searches + "" +
+// "Projects Viewed" + progress.projectViews + "" +
+// "Code Opens" + progress.codeOpens + "" +
+// "Projects Completed" + progress.completions + "";
+// }
+// if (meterFill) {
+// var percentage = Math.min(100, Math.round((progress.points / PROGRESS_MAX_POINTS) * 100));
+// meterFill.style.width = percentage + "%";
+// meterFill.setAttribute("aria-valuenow", String(percentage));
+// meterFill.textContent = percentage + "%";
+// }
+// if (badgesEl) {
+// var badges = [
+// ["first_search", "First Search"],
+// ["project_explorer", "Project Explorer"],
+// ["code_starter", "Code Starter"],
+// ["completionist", "Completionist"],
+// ["roadmap_runner", "Roadmap Runner"]
+// ];
+// badgesEl.innerHTML = badges.map(function (badge) {
+// var unlocked = progress.badges[badge[0]];
+// return "" + (unlocked ? "OK" : "*") + "" + badge[1] + "";
+// }).join("");
+// }
+// if (achievementList) {
+// achievementList.innerHTML = progress.achievements.length
+// ? progress.achievements.map(function (item) {
+// return "" + item.title + "" +
+// item.description + "" + item.date + "";
+// }).join("")
+// : "No achievements yet. Use DevPath and unlock the first badge.";
+// }
+// if (leaderboardList) {
+// var entries = [
+// { name: "Ava", points: 245 },
+// { name: "Kai", points: 192 },
+// { name: "Sam", points: 176 },
+// { name: "You", points: progress.points }
+// ].sort(function (a, b) { return b.points - a.points; });
+// leaderboardList.innerHTML = entries.map(function (entry, index) {
+// return "" + (index + 1) + ". " + entry.name + "" + entry.points + " pts";
+// }).join("");
+// }
+// if (historyList) {
+// historyList.innerHTML = progress.completedProjects.length
+// ? progress.completedProjects.slice(0, 5).map(function (item) {
+// var title = item && typeof item === "object" ? item.title : "Project " + item;
+// return "" + title + "Completed";
+// }).join("")
+// : "No completed projects yet. Mark one complete from a project page.";
+// }
+// if (completionBtn && typeof PROJECT_ID !== "undefined") {
+// var completed = projectIsCompleted(PROJECT_ID);
+// completionBtn.textContent = completed ? "Project Completed" : "Mark Project Complete";
+// completionBtn.disabled = completed;
+// }
+// }
+
+// function recordSearch() {
+// progress.searches += 1;
+// computeProgressPoints();
+// tryUnlockBadges();
+// saveProgressState();
+// updateProfileWidgets();
+// }
+
+// function recordProjectView() {
+// if (typeof PROJECT_ID === "undefined") return;
+// if (progress.viewedProjects.indexOf(PROJECT_ID) === -1) {
+// progress.viewedProjects.push(PROJECT_ID);
+// progress.projectViews = progress.viewedProjects.length;
+// computeProgressPoints();
+// tryUnlockBadges();
+// saveProgressState();
+// updateProfileWidgets();
+// }
+// }
+
+// function recordCodeOpen() {
+// progress.codeOpens += 1;
+// computeProgressPoints();
+// tryUnlockBadges();
+// saveProgressState();
+// updateProfileWidgets();
+// }
+
+// function recordCompletion(projectId, projectTitle) {
+// if (!projectId || projectIsCompleted(projectId)) return;
+// progress.completedProjects.push({ id: projectId, title: projectTitle || "Project " + projectId });
+// progress.completions = progress.completedProjects.length;
+// computeProgressPoints();
+// tryUnlockBadges();
+// saveProgressState();
+// updateProfileWidgets();
+// }
+
+// loadProgressState();
+// updateProfileWidgets();
+
+// (function initIndexPage() {
+// var form = document.getElementById("recommend-form");
+// if (!form) return;
+
+// var submitBtn = document.getElementById("submit-btn");
+// var btnLabel = document.getElementById("btn-label");
+// var btnLoading = document.getElementById("btn-loading");
+// var resultsSection = document.getElementById("results-section");
+// var resultsGrid = document.getElementById("results-grid");
+// var resultsLoadingEl = document.getElementById("results-loading");
+// var resultsEmptyEl = document.getElementById("results-empty");
+// var emptyMessageEl = document.getElementById("empty-message");
+// var skillsHidden = document.getElementById("skills");
+// var skillsInput = document.getElementById("skills-input");
+// var selectedChips = document.getElementById("skill-chips-selected");
+// var suggestions = document.getElementById("skills-suggestions");
+// var skillWrap = document.getElementById("skill-input-wrap");
+// var quickPickChips = Array.prototype.slice.call(document.querySelectorAll(".skill-chip"));
+// var selectedSkills = [];
+// var availableSkills = (typeof skills !== "undefined" && Array.isArray(skills))
+// ? skills.map(function (item) { return item.label; }).filter(Boolean)
+// : quickPickChips.map(function (chip) { return chip.getAttribute("data-skill"); });
+// var activeSuggestionIndex = -1;
+// var visibleSuggestions = [];
+
+// function normalize(value) {
+// return String(value || "").trim().toLowerCase();
+// }
+
+// function syncSkillsHiddenInput() {
+// skillsHidden.value = JSON.stringify(selectedSkills);
+// }
+
+// function isSelected(skill) {
+// return selectedSkills.some(function (item) { return normalize(item) === normalize(skill); });
+// }
+
+// function canonicalSkill(rawSkill) {
+// var trimmed = String(rawSkill || "").trim();
+// var match = availableSkills.find(function (skill) { return normalize(skill) === normalize(trimmed); });
+// return match || trimmed;
+// }
+
+// function updateQuickPickState() {
+// quickPickChips.forEach(function (chip) {
+// var active = isSelected(chip.getAttribute("data-skill"));
+// chip.classList.toggle("active", active);
+// chip.classList.toggle("selected", active);
+// chip.setAttribute("aria-pressed", active ? "true" : "false");
+// });
+// }
+
+// function renderSelectedChips() {
+// selectedChips.textContent = "";
+// selectedSkills.forEach(function (skill) {
+// var chip = document.createElement("span");
+// chip.className = "skill-chip-selected";
+// chip.appendChild(document.createTextNode(skill));
+// var button = document.createElement("button");
+// button.type = "button";
+// button.className = "skill-chip-remove";
+// button.setAttribute("aria-label", "Remove " + skill);
+// button.textContent = "x";
+// button.addEventListener("click", function (event) {
+// event.stopPropagation();
+// removeSkill(skill);
+// });
+// chip.appendChild(button);
+// selectedChips.appendChild(chip);
+// });
+// }
+
+// window.addSkill = function addSkill(rawSkill) {
+// var skill = canonicalSkill(rawSkill);
+// if (!skill || isSelected(skill)) return;
+// selectedSkills.push(skill);
+// renderSelectedChips();
+// syncSkillsHiddenInput();
+// updateQuickPickState();
+// clearFieldError("skills-error");
+// if (skillsInput) skillsInput.focus();
+// };
+
+// function removeSkill(skill) {
+// selectedSkills = selectedSkills.filter(function (item) { return normalize(item) !== normalize(skill); });
+// renderSelectedChips();
+// syncSkillsHiddenInput();
+// updateQuickPickState();
+// }
+
+// function clearFieldError(id) {
+// var el = document.getElementById(id);
+// if (el) el.textContent = "";
+// }
+
+// function showFieldError(id, message) {
+// var el = document.getElementById(id);
+// if (el) el.textContent = message;
+// }
+
+// function clearAllErrors() {
+// ["skills-error", "level-error", "interest-error", "time-error"].forEach(clearFieldError);
+// var general = document.getElementById("form-error-general");
+// if (general) general.textContent = "";
+// }
+
+// function hideSuggestions() {
+// visibleSuggestions = [];
+// activeSuggestionIndex = -1;
+// suggestions.style.display = "none";
+// suggestions.textContent = "";
+// skillsInput.setAttribute("aria-expanded", "false");
+// }
+
+// function filteredSkills(query) {
+// var q = normalize(query);
+// if (!q) return [];
+// return availableSkills.filter(function (skill) {
+// return normalize(skill).indexOf(q) !== -1 && !isSelected(skill);
+// }).slice(0, 8);
+// }
+
+// function renderSuggestionState() {
+// suggestions.querySelectorAll(".suggestion-item").forEach(function (item, index) {
+// item.classList.toggle("suggestion-item--active", index === activeSuggestionIndex);
+// item.setAttribute("aria-selected", index === activeSuggestionIndex ? "true" : "false");
+// });
+// }
+
+// function showSuggestions(items) {
+// visibleSuggestions = items;
+// activeSuggestionIndex = -1;
+// suggestions.textContent = "";
+// if (!items.length) {
+// hideSuggestions();
+// return;
+// }
+// items.forEach(function (skill, index) {
+// var item = document.createElement("div");
+// item.className = "suggestion-item";
+// item.id = "skills-suggestion-" + index;
+// item.setAttribute("role", "option");
+// item.setAttribute("aria-selected", "false");
+// item.textContent = skill;
+// item.addEventListener("mousedown", function (event) { event.preventDefault(); });
+// item.addEventListener("mouseenter", function () {
+// activeSuggestionIndex = index;
+// renderSuggestionState();
+// });
+// item.addEventListener("click", function () {
+// window.addSkill(skill);
+// skillsInput.value = "";
+// hideSuggestions();
+// });
+// suggestions.appendChild(item);
+// });
+// suggestions.style.display = "block";
+// skillsInput.setAttribute("aria-expanded", "true");
+// }
+
+// function validateForm() {
+// var valid = true;
+// if (!selectedSkills.length) {
+// showFieldError("skills-error", "Please add at least one skill.");
+// valid = false;
+// }
+// if (!document.getElementById("level").value) {
+// showFieldError("level-error", "Please select your experience level.");
+// valid = false;
+// }
+// if (!document.getElementById("interest").value) {
+// showFieldError("interest-error", "Please select an area of interest.");
+// valid = false;
+// }
+// if (!document.getElementById("time").value) {
+// showFieldError("time-error", "Please select your time availability.");
+// valid = false;
+// }
+// return valid;
+// }
+
+// function setLoadingState(isLoading) {
+// submitBtn.disabled = isLoading;
+// submitBtn.setAttribute("aria-busy", isLoading ? "true" : "false");
+// btnLabel.style.display = isLoading ? "none" : "inline";
+// btnLoading.style.display = isLoading ? "inline-flex" : "none";
+// if (isLoading) {
+// resultsSection.style.display = "block";
+// resultsLoadingEl.style.display = "block";
+// resultsGrid.style.display = "none";
+// resultsEmptyEl.style.display = "none";
+// resultsGrid.innerHTML = "";
+// resultsEmptyEl.style.display = "none";
+// resultsSection.scrollIntoView({ behavior: "smooth" });
+// } else {
+// resultsLoadingEl.style.display = "none";
+// }
+// }
+
+// function truncate(text, maxLength) {
+// text = text || "";
+// return text.length > maxLength ? text.slice(0, maxLength) + "..." : text;
+// }
+
+// function createTag(text, type) {
+// var span = document.createElement("span");
+// span.className = "project-tag project-tag--" + normalize(type).replace(/[^a-z0-9_-]/g, "-");
+// span.textContent = text;
+// return span;
+// }
+
+// function buildProjectCard(project) {
+// var card = document.createElement("div");
+// card.className = "project-card";
+
+// var title = document.createElement("h3");
+// title.className = "project-card-title";
+// title.textContent = project.title;
+
+// var desc = document.createElement("p");
+// desc.className = "project-card-desc";
+// var descText = document.createElement("span");
+// descText.className = "project-card-desc-text";
+// descText.textContent = truncate(project.description, 120);
+// desc.appendChild(descText);
+
+// if (project.description && project.description.length > 120) {
+// var expanded = false;
+// var readMore = document.createElement("button");
+// readMore.type = "button";
+// readMore.className = "read-more-btn";
+// readMore.textContent = "Read more";
+// readMore.setAttribute("aria-expanded", "false");
+// readMore.addEventListener("click", function () {
+// expanded = !expanded;
+// descText.textContent = expanded ? project.description : truncate(project.description, 120);
+// readMore.textContent = expanded ? "Read less" : "Read more";
+// readMore.setAttribute("aria-expanded", expanded ? "true" : "false");
+// });
+// desc.appendChild(readMore);
+// }
+
+// var tags = document.createElement("div");
+// tags.className = "project-card-tags";
+// (project.skills || []).forEach(function (skill) { tags.appendChild(createTag(skill, "skill")); });
+// tags.appendChild(createTag(project.level, project.level));
+// tags.appendChild(createTag("Time: " + project.time, "time"));
+
+// var footer = document.createElement("div");
+// footer.className = "project-card-footer";
+
+// if (typeof DevPathBookmarks !== "undefined") {
+// var saveBtn = document.createElement("button");
+// saveBtn.type = "button";
+// saveBtn.className = "btn-save-project";
+// saveBtn.setAttribute("data-save-project-id", project.id);
+// var isSaved = DevPathBookmarks.isSaved(project.id);
+// if (isSaved) saveBtn.classList.add("saved");
+// saveBtn.setAttribute("aria-pressed", isSaved ? "true" : "false");
+// DevPathBookmarks.setButtonContent(saveBtn, isSaved);
+// saveBtn.addEventListener("click", function () {
+// DevPathBookmarks.toggle(project, saveBtn);
+// });
+// footer.appendChild(saveBtn);
+// }
+
+// var link = document.createElement("a");
+// link.className = "btn-details";
+// link.textContent = "View Full Project";
+// link.href = "/project/" + project.id;
+// footer.appendChild(link);
+
+// card.appendChild(title);
+// card.appendChild(desc);
+// card.appendChild(tags);
+// card.appendChild(footer);
+// return card;
+// }
+
+// function renderResults(projects, message) {
+// resultsSection.style.display = "block";
+// resultsLoadingEl.style.display = "none";
+// resultsGrid.innerHTML = "";
+// if (!projects || projects.length === 0) {
+// resultsGrid.style.display = "none";
+// resultsEmptyEl.style.display = "block";
+// if (emptyMessageEl) {
+// emptyMessageEl.textContent = message || "Try adjusting your skills or choosing a different interest area.";
+// }
+// resultsSection.scrollIntoView({ behavior: "smooth" });
+// return;
+// }
+// resultsEmptyEl.style.display = "none";
+// resultsGrid.style.display = "grid";
+// projects.forEach(function (project) { resultsGrid.appendChild(buildProjectCard(project)); });
+// resultsSection.scrollIntoView({ behavior: "smooth" });
+// }
+
+// skillsInput.setAttribute("role", "combobox");
+// skillsInput.setAttribute("aria-expanded", "false");
+// suggestions.setAttribute("role", "listbox");
+
+// skillsInput.addEventListener("input", function () {
+// showSuggestions(filteredSkills(skillsInput.value));
+// });
+// skillsInput.addEventListener("focus", function () {
+// if (skillsInput.value.trim()) showSuggestions(filteredSkills(skillsInput.value));
+// });
+// skillsInput.addEventListener("blur", function () {
+// window.setTimeout(hideSuggestions, 150);
+// });
+// skillsInput.addEventListener("keydown", function (event) {
+// if (event.key === "ArrowDown" || event.key === "ArrowUp") {
+// if (!visibleSuggestions.length) showSuggestions(filteredSkills(skillsInput.value));
+// if (!visibleSuggestions.length) return;
+// event.preventDefault();
+// activeSuggestionIndex = event.key === "ArrowDown"
+// ? (activeSuggestionIndex + 1) % visibleSuggestions.length
+// : (activeSuggestionIndex <= 0 ? visibleSuggestions.length - 1 : activeSuggestionIndex - 1);
+// renderSuggestionState();
+// return;
+// }
+// if (event.key === "Escape") {
+// hideSuggestions();
+// return;
+// }
+// if (event.key === "Enter") {
+// event.preventDefault();
+// if (activeSuggestionIndex >= 0 && visibleSuggestions[activeSuggestionIndex]) {
+// window.addSkill(visibleSuggestions[activeSuggestionIndex]);
+// } else {
+// window.addSkill(skillsInput.value);
+// }
+// skillsInput.value = "";
+// hideSuggestions();
+// }
+// });
+
+// quickPickChips.forEach(function (chip) {
+// chip.addEventListener("click", function () {
+// var skill = chip.getAttribute("data-skill");
+// if (isSelected(skill)) removeSkill(skill);
+// else window.addSkill(skill);
+// skillsInput.value = "";
+// hideSuggestions();
+// });
+// });
+
+// if (skillWrap) {
+// skillWrap.addEventListener("click", function () { skillsInput.focus(); });
+// }
+
+// // Toggle dropdown on button click
+// var dropdownToggle = document.getElementById("skills-dropdown-toggle");
+// if (dropdownToggle) {
+// dropdownToggle.addEventListener("click", function (event) {
+// event.preventDefault();
+// event.stopPropagation();
+// var isExpanded = suggestions.style.display === "block";
+// if (isExpanded) {
+// hideSuggestions();
+// } else {
+// var unselectedSkills = availableSkills.filter(function (skill) {
+// return !isSelected(skill);
+// });
+// showSuggestions(unselectedSkills);
+// }
+// });
+// }
+
+// function resetFormAndState() {
+// form.reset();
+// selectedSkills = [];
+// renderSelectedChips();
+// syncSkillsHiddenInput();
+// updateQuickPickState();
+// clearAllErrors();
+// hideSuggestions();
+// resultsSection.style.display = "none";
+// if (skillsInput) skillsInput.focus();
+// }
+
+// var clearBtn = document.getElementById("clear-filters-btn");
+// if (clearBtn) {
+// clearBtn.addEventListener("click", resetFormAndState);
+// }
+
+// var inlineResetBtn = document.getElementById("reset-form-btn");
+// if (inlineResetBtn) {
+// inlineResetBtn.addEventListener("click", resetFormAndState);
+// }
+
+// var resetProgressBtn = document.getElementById("reset-progress-btn");
+// if (resetProgressBtn) {
+// resetProgressBtn.addEventListener("click", function () {
+// progress.searches = 0;
+// progress.projectViews = 0;
+// progress.codeOpens = 0;
+// progress.completions = 0;
+// progress.points = 0;
+// progress.viewedProjects = [];
+// progress.completedProjects = [];
+// progress.achievements = [];
+// progress.badges = {
+// first_search: false,
+// project_explorer: false,
+// code_starter: false,
+// completionist: false,
+// roadmap_runner: false
+// };
+// saveProgressState();
+// updateProfileWidgets();
+// showAchievementToast("Progress reset", "Your local profile has been cleared.");
+// });
+// }
+
+// form.addEventListener("submit", function (event) {
+// event.preventDefault();
+// clearAllErrors();
+// if (skillsInput.value.trim()) {
+// window.addSkill(skillsInput.value);
+// skillsInput.value = "";
+// hideSuggestions();
+// }
+// if (!validateForm()) return;
+// setLoadingState(true);
+// fetch("/api/recommend", {
+// method: "POST",
+// headers: { "Content-Type": "application/json" },
+// body: JSON.stringify({
+// skills: JSON.stringify(selectedSkills),
+// level: document.getElementById("level").value,
+// interest: document.getElementById("interest").value,
+// time: document.getElementById("time").value
+// })
+// })
+// .then(function (response) {
+// return response.json().then(function (data) {
+// if (!response.ok) throw new Error(data.error || "Unable to generate recommendations.");
+// return data;
+// });
+// })
+// .then(function (data) {
+// setLoadingState(false);
+// recordSearch();
+// renderResults(data.projects || [], data.message);
+// })
+// .catch(function (err) {
+// setLoadingState(false);
+// var general = document.getElementById("form-error-general");
+// if (general) general.textContent = err.message || "An unexpected error occurred. Please try again.";
+// });
+// });
+
+// var modal = document.getElementById("github-modal-overlay");
+// var openModalBtn = document.getElementById("btn-show-github");
+// var closeModalBtn = document.getElementById("btn-close-github");
+// var fetchBtn = document.getElementById("btn-fetch-github");
+// var githubInput = document.getElementById("github-username");
+// var errorMsg = document.getElementById("github-modal-error");
+
+// function closeGithubModal() {
+// modal.classList.remove("active");
+// githubInput.value = "";
+// errorMsg.textContent = "";
+// }
+
+// if (modal && openModalBtn && closeModalBtn && fetchBtn && githubInput && errorMsg) {
+// openModalBtn.addEventListener("click", function () {
+// modal.classList.add("active");
+// githubInput.focus();
+// });
+// closeModalBtn.addEventListener("click", closeGithubModal);
+// modal.addEventListener("click", function (event) {
+// if (event.target === modal) closeGithubModal();
+// });
+// fetchBtn.addEventListener("click", function () {
+// var username = githubInput.value.trim();
+// errorMsg.textContent = "";
+// if (!username) {
+// errorMsg.textContent = "Please enter a GitHub username.";
+// return;
+// }
+// fetchBtn.disabled = true;
+// fetchBtn.textContent = "Syncing...";
+// fetch("https://api.github.com/users/" + encodeURIComponent(username) + "/repos?sort=updated&per_page=100")
+// .then(function (response) {
+// if (!response.ok) throw new Error(response.status === 404 ? "Username not found." : "Unable to fetch GitHub repositories.");
+// return response.json();
+// })
+// .then(function (repos) {
+// var languages = [];
+// repos.forEach(function (repo) {
+// if (repo.language && languages.indexOf(repo.language) === -1) languages.push(repo.language);
+// });
+// if (!languages.length) {
+// errorMsg.textContent = "No public languages found.";
+// return;
+// }
+// languages.forEach(window.addSkill);
+// closeGithubModal();
+// })
+// .catch(function (err) {
+// errorMsg.textContent = err.message || "Failed to fetch skills.";
+// })
+// .finally(function () {
+// fetchBtn.disabled = false;
+// fetchBtn.textContent = "Fetch Skills";
+// });
+// });
+// }
+// })();
+
+// (function initDetailPage() {
+// if (typeof PROJECT_ID === "undefined") return;
+// recordProjectView();
+
+// var codePanel = document.getElementById("code-panel");
+// var codePanelOverlay = document.getElementById("code-panel-overlay");
+// var codeContentEl = document.getElementById("code-content");
+// var codePanelFilename = document.getElementById("code-panel-filename");
+// var btnViewCode = document.getElementById("btn-view-code");
+// var btnViewCodeSm = document.getElementById("btn-view-code-sm");
+// var btnClosePanel = document.getElementById("code-panel-close");
+// var btnCopyCode = document.getElementById("btn-copy-code");
+// var copyToast = document.getElementById("copy-toast");
+// var completionBtn = document.getElementById("btn-mark-complete");
+// var codeFetched = false;
+
+// function renderCode(code) {
+// codeContentEl.textContent = "";
+// String(code || "").split("\n").forEach(function (line, index) {
+// var row = document.createElement("div");
+// row.className = "code-line";
+// var number = document.createElement("span");
+// number.className = "code-line-number";
+// number.setAttribute("aria-hidden", "true");
+// number.textContent = index + 1;
+// var content = document.createElement("span");
+// content.className = "code-line-content";
+// content.textContent = line;
+// row.appendChild(number);
+// row.appendChild(content);
+// codeContentEl.appendChild(row);
+// });
+// }
+
+// function fetchStarterCode() {
+// codeContentEl.textContent = "Loading starter code...";
+// fetch("/project/" + PROJECT_ID + "/code")
+// .then(function (response) {
+// return response.json().then(function (data) {
+// if (!response.ok) throw new Error(data.error || "Starter code unavailable.");
+// return data;
+// });
+// })
+// .then(function (data) {
+// codePanelFilename.textContent = data.filename;
+// renderCode(data.code);
+// codeFetched = true;
+// })
+// .catch(function (err) {
+// codeContentEl.textContent = err.message || "Could not load starter code. Try downloading it instead.";
+// });
+// }
+
+// function openCodePanel() {
+// if (!codePanel) return;
+// codePanel.classList.add("active");
+// if (codePanelOverlay) codePanelOverlay.classList.add("active");
+// document.body.style.overflow = "hidden";
+// recordCodeOpen();
+// if (!codeFetched) fetchStarterCode();
+// }
+
+// function closeCodePanel() {
+// if (!codePanel) return;
+// codePanel.classList.remove("active");
+// if (codePanelOverlay) codePanelOverlay.classList.remove("active");
+// document.body.style.overflow = "";
+// }
+
+// if (btnViewCode) btnViewCode.addEventListener("click", openCodePanel);
+// if (btnViewCodeSm) btnViewCodeSm.addEventListener("click", openCodePanel);
+// if (btnClosePanel) btnClosePanel.addEventListener("click", closeCodePanel);
+// if (codePanelOverlay) codePanelOverlay.addEventListener("click", closeCodePanel);
+// document.addEventListener("keydown", function (event) {
+// if (event.key === "Escape") closeCodePanel();
+// });
+
+// if (btnCopyCode) {
+// btnCopyCode.addEventListener("click", function () {
+// var code = Array.prototype.slice.call(codeContentEl.querySelectorAll(".code-line-content"))
+// .map(function (line) { return line.textContent; })
+// .join("\n");
+// if (!code) return;
+// var done = function () {
+// if (copyToast) {
+// copyToast.classList.add("show");
+// window.setTimeout(function () { copyToast.classList.remove("show"); }, 2500);
+// }
+// };
+// if (navigator.clipboard && navigator.clipboard.writeText) {
+// navigator.clipboard.writeText(code).then(done);
+// } else {
+// var textarea = document.createElement("textarea");
+// textarea.value = code;
+// textarea.style.cssText = "position:fixed;top:-9999px;left:-9999px";
+// document.body.appendChild(textarea);
+// textarea.focus();
+// textarea.select();
+// try { document.execCommand("copy"); } catch (err) {}
+// document.body.removeChild(textarea);
+// done();
+// }
+// });
+// }
+
+// var roadmapCheckboxes = Array.prototype.slice.call(document.querySelectorAll(".roadmap-checkbox"));
+// var progressFill = document.getElementById("roadmap-progress-fill");
+// var progressText = document.getElementById("roadmap-progress-text");
+// var progressBar = document.querySelector(".roadmap-progress-bar");
+// var roadmapStorageKey = "devpath-roadmap-progress-" + PROJECT_ID;
+
+// function updateRoadmapProgress() {
+// if (!roadmapCheckboxes.length) return;
+// var completed = roadmapCheckboxes.filter(function (checkbox) { return checkbox.checked; }).length;
+// var percent = Math.round((completed / roadmapCheckboxes.length) * 100);
+// roadmapCheckboxes.forEach(function (checkbox) {
+// var step = checkbox.closest(".roadmap-step");
+// if (step) step.classList.toggle("completed", checkbox.checked);
+// });
+// if (progressFill) progressFill.style.width = percent + "%";
+// if (progressText) progressText.textContent = percent + "% completed";
+// if (progressBar) progressBar.setAttribute("aria-valuenow", String(percent));
+// try {
+// localStorage.setItem(roadmapStorageKey, JSON.stringify(roadmapCheckboxes.map(function (checkbox) {
+// return checkbox.checked;
+// })));
+// } catch (err) {}
+// }
+
+// try {
+// var saved = JSON.parse(localStorage.getItem(roadmapStorageKey) || "[]");
+// roadmapCheckboxes.forEach(function (checkbox, index) {
+// checkbox.checked = !!saved[index];
+// });
+// } catch (err) {}
+// roadmapCheckboxes.forEach(function (checkbox) {
+// checkbox.addEventListener("change", updateRoadmapProgress);
+// });
+// updateRoadmapProgress();
+
+// if (completionBtn) {
+// completionBtn.addEventListener("click", function () {
+// recordCompletion(PROJECT_ID, typeof PROJECT_TITLE !== "undefined" ? PROJECT_TITLE : "");
+// showAchievementToast("Project completed", "Nice work finishing this project.");
+// });
+// }
+// })();
+
+// (function initScrollButton() {
+// var button = document.getElementById("scroll-top-btn");
+// var icon = document.getElementById("scroll-btn-icon");
+// if (!button) return;
+// var atBottom = false;
+
+// function nearBottom() {
+// return window.innerHeight + window.pageYOffset >= document.body.scrollHeight - 40;
+// }
+
+// function update() {
+// button.classList.toggle("visible", window.pageYOffset > 200);
+// atBottom = nearBottom();
+// button.setAttribute("aria-label", atBottom ? "Scroll to top" : "Scroll to bottom");
+// button.title = atBottom ? "Scroll to top" : "Scroll to bottom";
+// if (icon) icon.innerHTML = atBottom ? '' : '';
+// }
+
+// window.addEventListener("scroll", update, { passive: true });
+// button.addEventListener("click", function () {
+// window.scrollTo({ top: atBottom ? 0 : document.body.scrollHeight, behavior: "smooth" });
+// });
+// update();
+// })();
// DevPath client-side behavior.
// Compatibility key for bookmarks.js: "devpathSavedProjects"
@@ -148,20 +1243,37 @@
var menu = document.getElementById("nav-mobile-menu");
if (!toggle || !menu) return;
+ // Defensive: avoid accidental form submission behavior
+ if (!toggle.getAttribute("type")) toggle.setAttribute("type", "button");
+
function setOpen(isOpen) {
menu.classList.toggle("open", isOpen);
toggle.classList.toggle("open", isOpen);
toggle.setAttribute("aria-expanded", isOpen ? "true" : "false");
}
- toggle.addEventListener("click", function () {
+ toggle.addEventListener("click", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
setOpen(!menu.classList.contains("open"));
});
+ // Only close menu when clicking actual navigation links, not buttons
menu.querySelectorAll(".nav-mobile-link").forEach(function (link) {
- link.addEventListener("click", function () {
+ if (link.tagName.toLowerCase() === "a") {
+ link.addEventListener("click", function () {
+ setOpen(false);
+ });
+ }
+ });
+
+ // Close when clicking outside the menu
+ document.addEventListener("click", function (e) {
+ if (menu.classList.contains("open") &&
+ !menu.contains(e.target) &&
+ !toggle.contains(e.target)) {
setOpen(false);
- });
+ }
});
window.addEventListener("resize", function () {
@@ -1282,4 +2394,4 @@ updateProfileWidgets();
window.scrollTo({ top: atBottom ? 0 : document.body.scrollHeight, behavior: "smooth" });
});
update();
-})();
+})();
\ No newline at end of file
diff --git a/src/static/style.css b/src/static/style.css
index 7721010a..474792e1 100644
--- a/src/static/style.css
+++ b/src/static/style.css
@@ -18,7 +18,7 @@
--indigo-600: #3347e0;
--indigo-500: #4f6ef7;
--indigo-100: #eef1ff;
- --indigo-50: #f5f7ff;
+ --indigo-50: #f5f7ff;
--purple-700: #5b21b6;
--purple-600: #7c3aed;
@@ -28,18 +28,18 @@
--yellow-300: #fcd34d;
--yellow-100: #fef9e7;
- --pink-100: #fce7f3;
- --pink-500: #ec4899;
+ --pink-100: #fce7f3;
+ --pink-500: #ec4899;
- --green-500: #10b981;
- --green-100: #d1fae5;
+ --green-500: #10b981;
+ --green-100: #d1fae5;
--orange-500: #f59e0b;
- --red-500: #ef4444;
+ --red-500: #ef4444;
/* ---- Neutrals ---- */
- --white: #ffffff;
- --gray-50: #f9fafb;
+ --white: #ffffff;
+ --gray-50: #f9fafb;
--gray-100: #f3f4f6;
--gray-200: #e5e7eb;
--gray-300: #d1d5db;
@@ -51,9 +51,9 @@
/* ---- Semantic text colours ---- */
--text-heading: var(--gray-900);
- --text-body: var(--gray-600);
- --text-light: var(--gray-400);
- --border: var(--gray-200);
+ --text-body: var(--gray-600);
+ --text-light: var(--gray-400);
+ --border: var(--gray-200);
/* =============================================================
SECTION 2: SEMANTIC THEME TOKENS (light defaults)
@@ -62,15 +62,20 @@
============================================================= */
/* Backgrounds */
- --bg-primary: #ffffff; /* page body background */
- --bg-secondary: #f9fafb; /* alternate section background */
+ --bg-primary: #ffffff;
+ /* page body background */
+ --bg-secondary: #f9fafb;
+ /* alternate section background */
/* Surfaces (cards, modals, inputs) */
- --surface: #ffffff; /* default card / form surface */
- --surface-hover: #f3f4f6; /* hovered surface */
+ --surface: #ffffff;
+ /* default card / form surface */
+ --surface-hover: #f3f4f6;
+ /* hovered surface */
/* Nav-specific mobile menu background */
--bg-mobile-menu: var(--indigo-900);
+ --bg-mobile-overlay: rgba(2, 6, 23, 0.56);
/* Body background for detail page */
--bg-page-detail: var(--gray-50);
@@ -83,32 +88,32 @@
--shadow-xl: 0 16px 60px rgba(15, 21, 96, 0.22);
/* Radii */
- --r-xs: 6px;
- --r-sm: 10px;
- --r-md: 16px;
- --r-lg: 24px;
- --r-xl: 32px;
+ --r-xs: 6px;
+ --r-sm: 10px;
+ --r-md: 16px;
+ --r-lg: 24px;
+ --r-xl: 32px;
--r-full: 9999px;
/* Typography */
--font-display: "Sora", sans-serif;
- --font-body: "Inter", sans-serif;
- --font-mono: "JetBrains Mono", "Courier New", monospace;
+ --font-body: "Inter", sans-serif;
+ --font-mono: "JetBrains Mono", "Courier New", monospace;
/* Transitions */
--t: 0.2s ease;
/* Entry animations (upstream) */
- --entry-duration: 700ms;
- --entry-delay-step: 110ms;
+ --entry-duration: 700ms;
+ --entry-delay-step: 110ms;
/* Accessibility — focus ring */
- --focus-ring-color: var(--yellow-400);
+ --focus-ring-color: var(--yellow-400);
--focus-ring-offset: 3px;
- --focus-ring-width: 2px;
+ --focus-ring-width: 2px;
/* Accent shortcuts (components reference these) */
- --accent: var(--indigo-600);
+ --accent: var(--indigo-600);
--accent-hover: var(--indigo-700);
--tag-beginner-text: #065f46;
--tag-intermediate-text: #78350f;
@@ -126,23 +131,27 @@
html[data-theme="dark"] {
/* ---- Semantic text colours ---- */
--text-heading: #e2e8f0;
- --text-body: #94a3b8;
- --text-light: #64748b;
+ --text-body: #94a3b8;
+ --text-light: #64748b;
/* ---- Border ---- */
--border: #1e293b;
/* ---- Semantic theme tokens ---- */
- --bg-primary: #080f1e; /* deep navy page body */
- --bg-secondary: #0d1526; /* slightly lighter sections */
- --surface: #0f172a; /* card / form surface */
- --surface-hover: #1e293b; /* hovered card surface */
+ --bg-primary: #080f1e;
+ /* deep navy page body */
+ --bg-secondary: #0d1526;
+ /* slightly lighter sections */
+ --surface: #0f172a;
+ /* card / form surface */
+ --surface-hover: #1e293b;
+ /* hovered card surface */
--bg-mobile-menu: #0d1526;
--bg-page-detail: #080f1e;
/* ---- Neutral scale remapped to dark equivalents ---- */
- --white: #0f172a;
- --gray-50: #1e293b;
+ --white: #0f172a;
+ --gray-50: #1e293b;
--gray-100: #1e293b;
--gray-200: #334155;
--gray-300: #475569;
@@ -153,14 +162,14 @@ html[data-theme="dark"] {
--gray-900: #f1f5f9;
/* ---- Indigo tints softened for dark surfaces ---- */
- --indigo-50: #1e2a4a;
+ --indigo-50: #1e2a4a;
--indigo-100: #1e3a6e;
/* ---- Colour tints ---- */
--purple-100: #2d1b69;
- --pink-100: #3b1130;
+ --pink-100: #3b1130;
--yellow-100: #3b2a00;
- --green-100: #052e16;
+ --green-100: #052e16;
/* ---- Shadows (darker tone looks heavy; compensate) ---- */
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.30);
@@ -181,9 +190,9 @@ html[data-theme="dark"] {
.theme-ready *::after {
transition:
background-color 0.3s ease,
- border-color 0.3s ease,
- color 0.3s ease,
- box-shadow 0.3s ease;
+ border-color 0.3s ease,
+ color 0.3s ease,
+ box-shadow 0.3s ease;
}
/* =============================================================
@@ -216,11 +225,21 @@ html[data-theme="dark"] {
}
/* Icon visibility controlled by data-theme on */
-.theme-toggle .icon-sun { display: none; }
-.theme-toggle .icon-moon { display: block; }
+.theme-toggle .icon-sun {
+ display: none;
+}
+
+.theme-toggle .icon-moon {
+ display: block;
+}
-html[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
-html[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
+html[data-theme="dark"] .theme-toggle .icon-sun {
+ display: block;
+}
+
+html[data-theme="dark"] .theme-toggle .icon-moon {
+ display: none;
+}
/* =============================================================
SECTION 6: RESET
@@ -329,6 +348,7 @@ ol {
opacity: 0;
transform: translate3d(0, 18px, 0);
}
+
to {
opacity: 1;
transform: translate3d(0, 0, 0);
@@ -336,8 +356,13 @@ ol {
}
@keyframes entrySoftFade {
- from { opacity: 0; }
- to { opacity: 1; }
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
}
html[data-entry-anim="true"] .navbar {
@@ -345,9 +370,9 @@ html[data-entry-anim="true"] .navbar {
animation: entrySoftFade 420ms ease forwards;
}
-html[data-entry-anim="true"] .hero-copy > *,
-html[data-entry-anim="true"] .hero-visual > *,
-html[data-entry-anim="true"] .stats-grid > *,
+html[data-entry-anim="true"] .hero-copy>*,
+html[data-entry-anim="true"] .hero-visual>*,
+html[data-entry-anim="true"] .stats-grid>*,
html[data-entry-anim="true"] .skill-strip-inner,
html[data-entry-anim="true"] .how-section .section-eyebrow,
html[data-entry-anim="true"] .how-section .section-title,
@@ -356,7 +381,7 @@ html[data-entry-anim="true"] .how-section .step-card,
html[data-entry-anim="true"] .features-section .section-eyebrow,
html[data-entry-anim="true"] .features-section .section-title,
html[data-entry-anim="true"] .features-section .section-sub,
-html[data-entry-anim="true"] .features-grid > *,
+html[data-entry-anim="true"] .features-grid>*,
html[data-entry-anim="true"] .form-section .section-eyebrow,
html[data-entry-anim="true"] .form-section .section-title,
html[data-entry-anim="true"] .form-section .section-sub,
@@ -367,61 +392,124 @@ html[data-entry-anim="true"] .form-card-outer {
will-change: transform, opacity;
}
-html[data-entry-anim="true"] .hero-copy > *:nth-child(1) { animation-delay: 90ms; }
-html[data-entry-anim="true"] .hero-copy > *:nth-child(2) { animation-delay: calc(90ms + var(--entry-delay-step)); }
-html[data-entry-anim="true"] .hero-copy > *:nth-child(3) { animation-delay: calc(90ms + (var(--entry-delay-step) * 2)); }
-html[data-entry-anim="true"] .hero-copy > *:nth-child(4) { animation-delay: calc(90ms + (var(--entry-delay-step) * 3)); }
+html[data-entry-anim="true"] .hero-copy>*:nth-child(1) {
+ animation-delay: 90ms;
+}
+
+html[data-entry-anim="true"] .hero-copy>*:nth-child(2) {
+ animation-delay: calc(90ms + var(--entry-delay-step));
+}
+
+html[data-entry-anim="true"] .hero-copy>*:nth-child(3) {
+ animation-delay: calc(90ms + (var(--entry-delay-step) * 2));
+}
+
+html[data-entry-anim="true"] .hero-copy>*:nth-child(4) {
+ animation-delay: calc(90ms + (var(--entry-delay-step) * 3));
+}
+
+html[data-entry-anim="true"] .hero-visual>*:nth-child(1) {
+ animation-delay: 160ms;
+}
+
+html[data-entry-anim="true"] .hero-visual>*:nth-child(2) {
+ animation-delay: 260ms;
+}
+
+html[data-entry-anim="true"] .hero-visual>*:nth-child(3) {
+ animation-delay: 360ms;
+}
+
+html[data-entry-anim="true"] .stats-grid>*:nth-child(1) {
+ animation-delay: 80ms;
+}
-html[data-entry-anim="true"] .hero-visual > *:nth-child(1) { animation-delay: 160ms; }
-html[data-entry-anim="true"] .hero-visual > *:nth-child(2) { animation-delay: 260ms; }
-html[data-entry-anim="true"] .hero-visual > *:nth-child(3) { animation-delay: 360ms; }
+html[data-entry-anim="true"] .stats-grid>*:nth-child(2) {
+ animation-delay: 170ms;
+}
-html[data-entry-anim="true"] .stats-grid > *:nth-child(1) { animation-delay: 80ms; }
-html[data-entry-anim="true"] .stats-grid > *:nth-child(2) { animation-delay: 170ms; }
-html[data-entry-anim="true"] .stats-grid > *:nth-child(3) { animation-delay: 260ms; }
+html[data-entry-anim="true"] .stats-grid>*:nth-child(3) {
+ animation-delay: 260ms;
+}
html[data-entry-anim="true"] .how-section .section-eyebrow,
html[data-entry-anim="true"] .features-section .section-eyebrow,
-html[data-entry-anim="true"] .form-section .section-eyebrow { animation-delay: 40ms; }
+html[data-entry-anim="true"] .form-section .section-eyebrow {
+ animation-delay: 40ms;
+}
html[data-entry-anim="true"] .how-section .section-title,
html[data-entry-anim="true"] .features-section .section-title,
-html[data-entry-anim="true"] .form-section .section-title { animation-delay: 120ms; }
+html[data-entry-anim="true"] .form-section .section-title {
+ animation-delay: 120ms;
+}
html[data-entry-anim="true"] .how-section .section-sub,
html[data-entry-anim="true"] .features-section .section-sub,
-html[data-entry-anim="true"] .form-section .section-sub { animation-delay: 200ms; }
+html[data-entry-anim="true"] .form-section .section-sub {
+ animation-delay: 200ms;
+}
+
+html[data-entry-anim="true"] .how-section .step-card:nth-child(1) {
+ animation-delay: 120ms;
+}
+
+html[data-entry-anim="true"] .how-section .step-card:nth-child(3) {
+ animation-delay: 210ms;
+}
+
+html[data-entry-anim="true"] .how-section .step-card:nth-child(5) {
+ animation-delay: 300ms;
+}
+
+html[data-entry-anim="true"] .features-grid>*:nth-child(1) {
+ animation-delay: 140ms;
+}
-html[data-entry-anim="true"] .how-section .step-card:nth-child(1) { animation-delay: 120ms; }
-html[data-entry-anim="true"] .how-section .step-card:nth-child(3) { animation-delay: 210ms; }
-html[data-entry-anim="true"] .how-section .step-card:nth-child(5) { animation-delay: 300ms; }
+html[data-entry-anim="true"] .features-grid>*:nth-child(2) {
+ animation-delay: 230ms;
+}
-html[data-entry-anim="true"] .features-grid > *:nth-child(1) { animation-delay: 140ms; }
-html[data-entry-anim="true"] .features-grid > *:nth-child(2) { animation-delay: 230ms; }
-html[data-entry-anim="true"] .features-grid > *:nth-child(3) { animation-delay: 320ms; }
+html[data-entry-anim="true"] .features-grid>*:nth-child(3) {
+ animation-delay: 320ms;
+}
-html[data-entry-anim="true"] .form-card-outer { animation-delay: 120ms; }
+html[data-entry-anim="true"] .form-card-outer {
+ animation-delay: 120ms;
+}
-html[data-entry-anim="true"] .form-card form > .form-group,
-html[data-entry-anim="true"] .form-card form > .skill-chips-row,
-html[data-entry-anim="true"] .form-card form > .form-row,
-html[data-entry-anim="true"] .form-card form > .btn-submit {
+html[data-entry-anim="true"] .form-card form>.form-group,
+html[data-entry-anim="true"] .form-card form>.skill-chips-row,
+html[data-entry-anim="true"] .form-card form>.form-row,
+html[data-entry-anim="true"] .form-card form>.btn-submit {
opacity: 0;
transform: translate3d(0, 14px, 0);
animation: entryFadeUp 600ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
will-change: transform, opacity;
}
-html[data-entry-anim="true"] .form-card form > .form-group:nth-child(1) { animation-delay: 180ms; }
-html[data-entry-anim="true"] .form-card form > .skill-chips-row { animation-delay: 250ms; }
-html[data-entry-anim="true"] .form-card form > .form-row { animation-delay: 320ms; }
-html[data-entry-anim="true"] .form-card form > .btn-submit { animation-delay: 390ms; }
+html[data-entry-anim="true"] .form-card form>.form-group:nth-child(1) {
+ animation-delay: 180ms;
+}
+
+html[data-entry-anim="true"] .form-card form>.skill-chips-row {
+ animation-delay: 250ms;
+}
+
+html[data-entry-anim="true"] .form-card form>.form-row {
+ animation-delay: 320ms;
+}
+
+html[data-entry-anim="true"] .form-card form>.btn-submit {
+ animation-delay: 390ms;
+}
@media (prefers-reduced-motion: reduce) {
+
html[data-entry-anim="true"] .navbar,
- html[data-entry-anim="true"] .hero-copy > *,
- html[data-entry-anim="true"] .hero-visual > *,
- html[data-entry-anim="true"] .stats-grid > *,
+ html[data-entry-anim="true"] .hero-copy>*,
+ html[data-entry-anim="true"] .hero-visual>*,
+ html[data-entry-anim="true"] .stats-grid>*,
html[data-entry-anim="true"] .skill-strip-inner,
html[data-entry-anim="true"] .how-section .section-eyebrow,
html[data-entry-anim="true"] .how-section .section-title,
@@ -430,15 +518,15 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
html[data-entry-anim="true"] .features-section .section-eyebrow,
html[data-entry-anim="true"] .features-section .section-title,
html[data-entry-anim="true"] .features-section .section-sub,
- html[data-entry-anim="true"] .features-grid > *,
+ html[data-entry-anim="true"] .features-grid>*,
html[data-entry-anim="true"] .form-section .section-eyebrow,
html[data-entry-anim="true"] .form-section .section-title,
html[data-entry-anim="true"] .form-section .section-sub,
html[data-entry-anim="true"] .form-card-outer,
- html[data-entry-anim="true"] .form-card form > .form-group,
- html[data-entry-anim="true"] .form-card form > .skill-chips-row,
- html[data-entry-anim="true"] .form-card form > .form-row,
- html[data-entry-anim="true"] .form-card form > .btn-submit {
+ html[data-entry-anim="true"] .form-card form>.form-group,
+ html[data-entry-anim="true"] .form-card form>.skill-chips-row,
+ html[data-entry-anim="true"] .form-card form>.form-row,
+ html[data-entry-anim="true"] .form-card form>.btn-submit {
animation: none;
opacity: 1;
transform: none;
@@ -578,6 +666,7 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
background: rgba(255, 255, 255, 0.11);
box-shadow: 0 0 0 3px rgba(79, 110, 247, 0.25);
}
+
#topic-search,
#topic-search-mobile {
flex: 1;
@@ -631,6 +720,7 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
width: 16px;
height: 16px;
}
+
.nav-right {
display: flex;
align-items: center;
@@ -682,7 +772,7 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
opacity: 0;
transition:
transform 0.35s cubic-bezier(0.4, 0, 0.2, 1),
- opacity 0.25s ease;
+ opacity 0.25s ease;
}
.nav-link:hover,
@@ -726,6 +816,188 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
}
/* Mobile hamburger button */
+.nav-mobile-toggle {
+ display: none;
+ width: 42px;
+ height: 42px;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 5px;
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ border-radius: 10px;
+ background: rgba(255, 255, 255, 0.08);
+ cursor: pointer;
+ padding: 0;
+ margin-left: auto;
+ position: relative;
+ z-index: 1301;
+ transition: background var(--t), border-color var(--t), transform var(--t);
+}
+
+.nav-mobile-toggle:hover {
+ background: rgba(255, 255, 255, 0.14);
+ border-color: rgba(255, 255, 255, 0.35);
+}
+
+.nav-mobile-toggle:focus-visible {
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
+ outline-offset: var(--focus-ring-offset);
+ border-radius: 10px;
+}
+
+.nav-mobile-toggle span {
+ display: block;
+ width: 18px;
+ height: 2px;
+ background: #ffffff;
+ border-radius: 2px;
+ transition: transform .22s ease, opacity .18s ease;
+}
+
+.nav-mobile-toggle.open span:nth-child(1) {
+ transform: translateY(7px) rotate(45deg);
+}
+
+.nav-mobile-toggle.open span:nth-child(2) {
+ opacity: 0;
+}
+
+.nav-mobile-toggle.open span:nth-child(3) {
+ transform: translateY(-7px) rotate(-45deg);
+}
+
+/* Mobile drawer */
+.nav-mobile-menu {
+ display: flex;
+ flex-direction: column;
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: auto;
+ width: min(86vw, 340px);
+ height: 100dvh;
+ padding: 78px 16px 16px;
+ background: var(--bg-mobile-menu);
+ border-left: 1px solid rgba(255, 255, 255, 0.08);
+ box-shadow: -16px 0 36px rgba(0, 0, 0, 0.3);
+ z-index: 1300;
+ overflow-y: auto;
+ transform: translateX(100%);
+ opacity: 1;
+ pointer-events: none;
+ transition: transform .28s ease;
+}
+
+/* Backdrop */
+.nav-mobile-menu::before {
+ content: "";
+ position: fixed;
+ inset: 0;
+ background: var(--bg-mobile-overlay);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity .25s ease;
+ z-index: -1;
+}
+
+.nav-mobile-menu.open {
+ transform: translateX(0);
+ pointer-events: auto;
+}
+
+.nav-mobile-menu.open::before {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.nav-mobile-link {
+ position: relative;
+ font-size: 0.96rem;
+ font-weight: 600;
+ color: rgba(255, 255, 255, 0.88);
+ padding: 11px 10px;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.07);
+ border-radius: 10px;
+ transition: color var(--t), background var(--t);
+}
+
+.nav-mobile-link::after {
+ content: '';
+ position: absolute;
+ left: 10px;
+ right: 10px;
+ bottom: 4px;
+ height: 2px;
+ background: linear-gradient(90deg, var(--indigo-500), var(--yellow-400));
+ border-radius: 999px;
+ transform: scaleX(0);
+ transform-origin: left;
+ opacity: 0;
+ transition: transform .3s ease, opacity .2s ease;
+}
+
+.nav-mobile-link:hover,
+.nav-mobile-link.active {
+ color: #ffffff;
+ background: rgba(255, 255, 255, 0.06);
+ text-decoration: none;
+}
+
+.nav-mobile-link:hover::after,
+.nav-mobile-link.active::after {
+ transform: scaleX(1);
+ opacity: 1;
+}
+
+.nav-mobile-link:focus-visible {
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
+ outline-offset: var(--focus-ring-offset);
+ border-radius: var(--r-xs);
+}
+
+.nav-mobile-link:last-child {
+ border-bottom: none;
+}
+
+/* Mobile search in drawer */
+.navbar-search.navbar-search--mobile {
+ width: 100%;
+ max-width: 100%;
+ margin: 0 0 14px 0;
+ align-self: stretch;
+ flex-direction: row-reverse;
+}
+
+.navbar-search--mobile .navbar-search-btn {
+ width: 36px;
+ height: 36px;
+ margin: 2px;
+ padding: 0;
+ border-radius: 999px;
+ background: rgba(255, 255, 255, 0.12);
+ border: none;
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.nav-mobile-menu .theme-toggle {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ background: rgba(255, 255, 255, 0.06);
+ border: 1px solid rgba(255, 255, 255, 0.12);
+ text-align: left;
+ cursor: pointer;
+ width: 100%;
+ padding: 10px 12px;
+ font-size: 0.95rem;
+ font-weight: 500;
+ color: rgba(255, 255, 255, 0.9);
+ border-radius: 10px;
+ margin-top: 8px;
+}
+
+/* Mobile hamburger button
.nav-mobile-toggle {
display: none;
flex-direction: column;
@@ -769,10 +1041,10 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
display: none;
flex-direction: column;
position: fixed;
- top: 0;
+ top: 64px;
+ height: calc(100vh - 64px);
left: 0;
width: 100%;
- height: 100vh;
padding: 100px 32px 20px;
background: var(--indigo-900);
@@ -795,7 +1067,7 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
}
/* Animated underline for mobile links */
-.nav-mobile-link::after {
+/* .nav-mobile-link::after {
content: '';
position: absolute;
left: 0;
@@ -833,7 +1105,7 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
.nav-mobile-link:last-child {
border-bottom: none;
-}
+}
/* Responsive navbar — tighten before switching to mobile menu */
@media (max-width: 1100px) {
@@ -871,11 +1143,10 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
}
.navbar-search.navbar-search--mobile {
- flex: 0 0 auto;
- width: 100%;
- max-width: 100%;
- margin-left: 0;
- align-self: stretch;
+ flex: none !important;
+ width: 100% !important;
+ max-width: 100% !important;
+ margin: 0 0 14px 0 !important;
flex-direction: row-reverse;
}
@@ -919,11 +1190,16 @@ html[data-entry-anim="true"] .form-card form > .btn-submit { animat
}
/* Mobile toggle label: CSS content updates automatically without JS */
-.theme-toggle-label { font-size: 0; } /* hide raw text node */
+.theme-toggle-label {
+ font-size: 0;
+}
+
+/* hide raw text node */
.theme-toggle-label::before {
content: "Dark Mode";
font-size: 0.95rem;
}
+
html[data-theme="dark"] .theme-toggle-label::before {
content: "Light Mode";
}
@@ -1157,9 +1433,17 @@ html[data-theme="dark"] .theme-toggle-label::before {
flex-shrink: 0;
}
-.hvm-dot--red { background: #ff5f56; }
-.hvm-dot--yellow { background: #ffbd2e; }
-.hvm-dot--green { background: #27c93f; }
+.hvm-dot--red {
+ background: #ff5f56;
+}
+
+.hvm-dot--yellow {
+ background: #ffbd2e;
+}
+
+.hvm-dot--green {
+ background: #27c93f;
+}
.hvm-filename {
font-family: var(--font-mono);
@@ -1178,15 +1462,35 @@ html[data-theme="dark"] .theme-toggle-label::before {
line-height: 1.85;
}
-.hvm-line { display: block; color: #e6edf3; }
-.hvm-indent { padding-left: 20px; }
-.hvm-indent2 { padding-left: 40px; }
+.hvm-line {
+ display: block;
+ color: #e6edf3;
+}
+
+.hvm-indent {
+ padding-left: 20px;
+}
+
+.hvm-indent2 {
+ padding-left: 40px;
+}
/* Code syntax colours — always on dark background, no theming needed */
-.hvm-kw { color: #ff7b72; }
-.hvm-fn { color: #d2a8ff; }
-.hvm-cm { color: #8b949e; }
-.hvm-op { color: #79c0ff; }
+.hvm-kw {
+ color: #ff7b72;
+}
+
+.hvm-fn {
+ color: #d2a8ff;
+}
+
+.hvm-cm {
+ color: #8b949e;
+}
+
+.hvm-op {
+ color: #79c0ff;
+}
/* Hero decorative blobs */
.hero-blob {
@@ -1256,9 +1560,20 @@ html[data-theme="dark"] .theme-toggle-label::before {
flex-shrink: 0;
}
-.stat-icon--indigo { background: var(--indigo-100); color: var(--indigo-600); }
-.stat-icon--green { background: var(--green-100); color: var(--green-500); }
-.stat-icon--yellow { background: var(--yellow-100); color: var(--orange-500); }
+.stat-icon--indigo {
+ background: var(--indigo-100);
+ color: var(--indigo-600);
+}
+
+.stat-icon--green {
+ background: var(--green-100);
+ color: var(--green-500);
+}
+
+.stat-icon--yellow {
+ background: var(--yellow-100);
+ color: var(--orange-500);
+}
.stat-info {
display: flex;
@@ -1388,11 +1703,11 @@ html[data-theme="dark"] .theme-toggle-label::before {
padding: 6px 14px;
box-shadow: 0 1px 2px rgba(15, 21, 96, 0.04);
transition:
- transform 180ms ease,
- background 180ms ease,
- color 180ms ease,
- border-color 180ms ease,
- box-shadow 180ms ease;
+ transform 180ms ease,
+ background 180ms ease,
+ color 180ms ease,
+ border-color 180ms ease,
+ box-shadow 180ms ease;
}
.ss-item:hover {
@@ -1435,8 +1750,13 @@ html[data-theme="dark"] .theme-toggle-label::before {
}
@keyframes skill-strip-marquee {
- from { transform: translateX(0); }
- to { transform: translateX(-50%); }
+ from {
+ transform: translateX(0);
+ }
+
+ to {
+ transform: translateX(-50%);
+ }
}
.ss-item-pink {
@@ -1450,8 +1770,11 @@ html[data-theme="dark"] .theme-toggle-label::before {
}
@media (prefers-reduced-motion: reduce) {
+
/* Universal reduced-motion reset: instantly disables high-impact transitions and structural animations */
- *, ::before, ::after {
+ *,
+ ::before,
+ ::after {
animation-delay: -1ms !important;
animation-duration: 1ms !important;
animation-iteration-count: 1 !important;
@@ -1598,9 +1921,17 @@ html[data-theme="dark"] .theme-toggle-label::before {
box-shadow: var(--shadow-md);
}
-.feature-card--pink { background: var(--pink-100); }
-.feature-card--yellow { background: var(--yellow-100); }
-.feature-card--purple { background: var(--purple-100); }
+.feature-card--pink {
+ background: var(--pink-100);
+}
+
+.feature-card--yellow {
+ background: var(--yellow-100);
+}
+
+.feature-card--purple {
+ background: var(--purple-100);
+}
.feature-card-icon {
width: 52px;
@@ -1614,9 +1945,17 @@ html[data-theme="dark"] .theme-toggle-label::before {
box-shadow: var(--shadow-xs);
}
-.feature-card--pink .feature-card-icon { color: var(--pink-500); }
-.feature-card--yellow .feature-card-icon { color: var(--orange-500); }
-.feature-card--purple .feature-card-icon { color: var(--purple-600); }
+.feature-card--pink .feature-card-icon {
+ color: var(--pink-500);
+}
+
+.feature-card--yellow .feature-card-icon {
+ color: var(--orange-500);
+}
+
+.feature-card--purple .feature-card-icon {
+ color: var(--purple-600);
+}
.feature-card h3 {
font-family: var(--font-display);
@@ -1834,6 +2173,7 @@ label {
opacity: 0;
transform: translateY(-8px);
}
+
to {
opacity: 1;
transform: translateY(0);
@@ -1911,10 +2251,22 @@ label {
}
/* Scrollbar styling for suggestions dropdown */
-.skills-suggestions::-webkit-scrollbar { width: 6px; }
-.skills-suggestions::-webkit-scrollbar-track { background: var(--gray-50); }
-.skills-suggestions::-webkit-scrollbar-thumb { background: var(--indigo-500); border-radius: 3px; }
-.skills-suggestions::-webkit-scrollbar-thumb:hover { background: var(--indigo-600); }
+.skills-suggestions::-webkit-scrollbar {
+ width: 6px;
+}
+
+.skills-suggestions::-webkit-scrollbar-track {
+ background: var(--gray-50);
+}
+
+.skills-suggestions::-webkit-scrollbar-thumb {
+ background: var(--indigo-500);
+ border-radius: 3px;
+}
+
+.skills-suggestions::-webkit-scrollbar-thumb:hover {
+ background: var(--indigo-600);
+}
/* Quick-select chips row */
.skill-chips-row {
@@ -2185,8 +2537,13 @@ body.dark-theme .btn-clear:hover {
}
@keyframes fadeIn {
- from { opacity: 0; }
- to { opacity: 1; }
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
}
/* Loading state UI (button spinner) */
@@ -2207,7 +2564,9 @@ body.dark-theme .btn-clear:hover {
}
@keyframes spin {
- to { transform: rotate(360deg); }
+ to {
+ transform: rotate(360deg);
+ }
}
/* =============================================================
@@ -2240,14 +2599,23 @@ body.dark-theme .btn-clear:hover {
animation: dotBounce 1.2s ease-in-out infinite;
}
-.loading-dots span:nth-child(2) { animation-delay: 0.2s; }
-.loading-dots span:nth-child(3) { animation-delay: 0.4s; }
+.loading-dots span:nth-child(2) {
+ animation-delay: 0.2s;
+}
+
+.loading-dots span:nth-child(3) {
+ animation-delay: 0.4s;
+}
@keyframes dotBounce {
- 0%, 80%, 100% {
+
+ 0%,
+ 80%,
+ 100% {
transform: scale(0.6);
opacity: 0.4;
}
+
40% {
transform: scale(1.1);
opacity: 1;
@@ -2259,6 +2627,7 @@ body.dark-theme .btn-clear:hover {
opacity: 0;
transform: translateY(10px);
}
+
to {
opacity: 1;
transform: translateY(0);
@@ -2415,11 +2784,30 @@ body.dark-theme .btn-clear:hover {
border-radius: var(--r-full);
}
-.project-tag--skill { background: var(--indigo-100); color:white; }
-.project-tag--time { background: var(--gray-100); color: var(--gray-600); }
-.project-tag--beginner { background: var(--green-100); color: #065f46; }
-.project-tag--intermediate { background: var(--yellow-100); color: #78350f; }
-.project-tag--advanced { background: #fee2e2; color: #7f1d1d; }
+.project-tag--skill {
+ background: var(--indigo-100);
+ color: var(--indigo-700);
+}
+
+.project-tag--time {
+ background: var(--gray-100);
+ color: var(--gray-600);
+}
+
+.project-tag--beginner {
+ background: var(--green-100);
+ color: #065f46;
+}
+
+.project-tag--intermediate {
+ background: var(--yellow-100);
+ color: #78350f;
+}
+
+.project-tag--advanced {
+ background: #fee2e2;
+ color: #7f1d1d;
+}
.project-card-footer {
display: grid;
@@ -2792,9 +3180,20 @@ body.dark-theme .btn-clear:hover {
border-radius: var(--r-full);
}
-.detail-tag--level { background: rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.85); }
-.detail-tag--interest { background: rgba(6, 182, 212, 0.18); color: #a7f3f9; }
-.detail-tag--time { background: rgba(251, 191, 36, 0.18); color: var(--yellow-300); }
+.detail-tag--level {
+ background: rgba(255, 255, 255, 0.12);
+ color: rgba(255, 255, 255, 0.85);
+}
+
+.detail-tag--interest {
+ background: rgba(6, 182, 212, 0.18);
+ color: #a7f3f9;
+}
+
+.detail-tag--time {
+ background: rgba(251, 191, 36, 0.18);
+ color: var(--yellow-300);
+}
.detail-title {
font-family: var(--font-display);
@@ -3000,67 +3399,71 @@ body.dark-theme .btn-clear:hover {
margin: 4px 0;
}
-.roadmap-step:last-child .roadmap-line { display: none; }
+.roadmap-step:last-child .roadmap-line {
+ display: none;
+}
+
/* Roadmap timeline structure */
-.roadmap-timeline{
- display:flex;
- flex-direction:column;
- width:100%;
- padding:0;
- margin:0;
+.roadmap-timeline {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ padding: 0;
+ margin: 0;
}
-.roadmap-step{
- display:flex;
- width:100%;
- list-style:none;
+.roadmap-step {
+ display: flex;
+ width: 100%;
+ list-style: none;
}
-.roadmap-marker{
- display:flex;
- flex-direction:column;
- align-items:center;
- flex-shrink:0;
- width:36px;
+.roadmap-marker {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ flex-shrink: 0;
+ width: 36px;
}
-.roadmap-dot{
- width:14px;
- height:14px;
- border-radius:50%;
- background:var(--surface);
- border:3px solid var(--indigo-600);
- margin-top:4px;
- box-sizing:border-box;
+.roadmap-dot {
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ background: var(--surface);
+ border: 3px solid var(--indigo-600);
+ margin-top: 4px;
+ box-sizing: border-box;
}
-.roadmap-line{
- flex:1;
- width:0;
- border-left:2px dashed var(--border);
- background:transparent;
- margin:4px 0;
+.roadmap-line {
+ flex: 1;
+ width: 0;
+ border-left: 2px dashed var(--border);
+ background: transparent;
+ margin: 4px 0;
}
-.roadmap-step:last-child .roadmap-line{
- display:none;
+.roadmap-step:last-child .roadmap-line {
+ display: none;
}
-.roadmap-content{
- padding:0 0 28px 16px;
- flex:1;
+
+.roadmap-content {
+ padding: 0 0 28px 16px;
+ flex: 1;
}
/* keep checkbox row aligned */
-.roadmap-step-label{
- display:flex;
- align-items:flex-start;
- gap:12px;
+.roadmap-step-label {
+ display: flex;
+ align-items: flex-start;
+ gap: 12px;
}
-.roadmap-text-wrap{
- display:flex;
- flex-direction:column;
- gap:6px;
+.roadmap-text-wrap {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
}
.roadmap-step:last-child .roadmap-line {
@@ -3120,47 +3523,46 @@ body.dark-theme .btn-clear:hover {
}
/* Progress container */
-.roadmap-progress-wrap{
- display:flex;
- align-items:center;
- gap:14px;
- width:100%;
- margin:18px 0 28px;
+.roadmap-progress-wrap {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ width: 100%;
+ margin: 18px 0 28px;
}
/* Actual bar */
-.roadmap-progress-bar{
- flex:1;
- width:100%;
- max-width:100%;
- height:10px;
- background:#e5e7eb;
- border-radius:999px;
- overflow:hidden;
- border:1px solid #d1d5db;
+.roadmap-progress-bar {
+ flex: 1;
+ width: 100%;
+ max-width: 100%;
+ height: 10px;
+ background: #e5e7eb;
+ border-radius: 999px;
+ overflow: hidden;
+ border: 1px solid #d1d5db;
}
/* Fill animation */
-#roadmap-progress-fill{
- height:100%;
- width:0%;
- border-radius:999px;
- background:linear-gradient(
- 90deg,
- #4f46e5,
- #9333ea
- );
- transition:width .35s ease;
+#roadmap-progress-fill {
+ height: 100%;
+ width: 0%;
+ border-radius: 999px;
+ background: linear-gradient(90deg,
+ #4f46e5,
+ #9333ea);
+ transition: width .35s ease;
}
/* Percentage text */
-#roadmap-progress-text{
- white-space:nowrap;
- min-width:120px;
- font-size:.85rem;
- font-weight:600;
- color:#6b7280;
+#roadmap-progress-text {
+ white-space: nowrap;
+ min-width: 120px;
+ font-size: .85rem;
+ font-weight: 600;
+ color: #6b7280;
}
+
/* Resources list */
.resource-list {
display: flex;
@@ -3283,9 +3685,17 @@ body.dark-theme .btn-clear:hover {
}
/* Difficulty colours — light theme */
-.stats-value--beginner { color: #065f46; }
-.stats-value--intermediate { color: #78350f; }
-.stats-value--advanced { color: #7f1d1d; }
+.stats-value--beginner {
+ color: #065f46;
+}
+
+.stats-value--intermediate {
+ color: #78350f;
+}
+
+.stats-value--advanced {
+ color: #7f1d1d;
+}
.sidebar-card-desc {
font-size: 0.85rem;
@@ -3610,7 +4020,7 @@ body.dark-theme .btn-clear:hover {
color: #ffffff;
font-size: 0.8rem;
font-weight: 700;
- text-shadow: 0 1px 2px rgba(0,0,0,0.4);
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
transition: width 0.4s ease;
}
@@ -4101,13 +4511,16 @@ body.dark-theme .btn-clear:hover {
accidental overlap on mid-sized viewports
============================================================= */
.hero-visual {
- gap: 18px; /* slightly larger gap to avoid tight stacking */
+ gap: 18px;
+ /* slightly larger gap to avoid tight stacking */
}
.hero-visual-main {
position: relative;
- z-index: 3; /* keep code preview above floating cards when necessary */
- min-height: 220px; /* ensure preview has vertical space on narrow viewports */
+ z-index: 3;
+ /* keep code preview above floating cards when necessary */
+ min-height: 220px;
+ /* ensure preview has vertical space on narrow viewports */
}
.hero-visual-card {
@@ -4119,12 +4532,14 @@ body.dark-theme .btn-clear:hover {
can sometimes visually overlap hero content at certain widths. This
override is scoped to the immediate following section to minimize
layout changes elsewhere. */
-.hero + .stats-section {
+.hero+.stats-section {
margin-top: -20px;
}
@media (max-width: 1024px) {
- .hero-visual-main { min-height: 260px; }
+ .hero-visual-main {
+ min-height: 260px;
+ }
}
@@ -4378,8 +4793,13 @@ html[data-theme="dark"] .skill-chip-selected {
border-color: rgba(99, 102, 241, 0.3);
}
-html[data-theme="dark"] .skill-chip-remove { color: #a5b4fc; }
-html[data-theme="dark"] .skill-chip-remove:hover { color: #f87171; }
+html[data-theme="dark"] .skill-chip-remove {
+ color: #a5b4fc;
+}
+
+html[data-theme="dark"] .skill-chip-remove:hover {
+ color: #f87171;
+}
/* Quick-pick chips (available row) */
html[data-theme="dark"] .skill-chip {
@@ -4396,14 +4816,33 @@ html[data-theme="dark"] .skill-chip.active {
}
/* Difficulty colours — light green/amber/red unreadable on dark surfaces */
-html[data-theme="dark"] .stats-value--beginner { color: #6ee7b7; }
-html[data-theme="dark"] .stats-value--intermediate { color: #fcd34d; }
-html[data-theme="dark"] .stats-value--advanced { color: #fca5a5; }
+html[data-theme="dark"] .stats-value--beginner {
+ color: #6ee7b7;
+}
+
+html[data-theme="dark"] .stats-value--intermediate {
+ color: #fcd34d;
+}
+
+html[data-theme="dark"] .stats-value--advanced {
+ color: #fca5a5;
+}
/* Project tag level variants */
-html[data-theme="dark"] .project-tag--beginner { color: #6ee7b7; background: #052e16; }
-html[data-theme="dark"] .project-tag--intermediate { color: #fcd34d; background: #3b2a00; }
-html[data-theme="dark"] .project-tag--advanced { color: #fca5a5; background: #3b0f0f; }
+html[data-theme="dark"] .project-tag--beginner {
+ color: #6ee7b7;
+ background: #052e16;
+}
+
+html[data-theme="dark"] .project-tag--intermediate {
+ color: #fcd34d;
+ background: #3b2a00;
+}
+
+html[data-theme="dark"] .project-tag--advanced {
+ color: #fca5a5;
+ background: #3b0f0f;
+}
/* Sidebar code card gradient — adjusted for dark surfaces */
html[data-theme="dark"] .sidebar-card--code {
@@ -4418,6 +4857,10 @@ html[data-theme="dark"] .btn-view-code-sm {
border-color: rgba(99, 102, 241, 0.4);
}
+#scroll-top-btn.visible {
+ display: flex;
+}
+
/* DARK MODE */
body.dark-theme {
background: #0b1120;
@@ -4427,12 +4870,12 @@ body.dark-theme {
/* NAVBAR */
body.dark-theme .navbar {
background: rgba(10, 15, 35, 0.96);
- border-bottom: 1px solid rgba(255,255,255,0.06);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
body.dark-theme .nav-link,
body.dark-theme .nav-mobile-link {
- color: rgba(255,255,255,0.82);
+ color: rgba(255, 255, 255, 0.82);
}
body.dark-theme .nav-link:hover,
@@ -4462,14 +4905,12 @@ body.dark-theme .nav-mobile-menu {
body.dark-theme .hero {
background:
radial-gradient(circle at top left,
- rgba(99,102,241,0.22),
+ rgba(99, 102, 241, 0.22),
transparent 32%),
- linear-gradient(
- 135deg,
+ linear-gradient(135deg,
#0f172a 0%,
#1e1b4b 55%,
- #4c1d95 100%
- );
+ #4c1d95 100%);
}
body.dark-theme .hero-heading {
@@ -4477,25 +4918,25 @@ body.dark-theme .hero-heading {
}
body.dark-theme .hero-subtext {
- color: rgba(255,255,255,0.78);
+ color: rgba(255, 255, 255, 0.78);
}
/* hero buttons */
body.dark-theme .btn-hero-ghost {
color: white;
- border-color: rgba(255,255,255,0.16);
- background: rgba(255,255,255,0.06);
+ border-color: rgba(255, 255, 255, 0.16);
+ background: rgba(255, 255, 255, 0.06);
}
body.dark-theme .btn-hero-ghost:hover {
- background: rgba(255,255,255,0.12);
+ background: rgba(255, 255, 255, 0.12);
}
/* hero floating cards */
body.dark-theme .hero-visual-card {
- background: rgba(255,255,255,0.96);
+ background: rgba(255, 255, 255, 0.96);
}
body.dark-theme .hvc-title {
@@ -4518,7 +4959,7 @@ body.dark-theme .stats-section {
body.dark-theme .skill-strip {
background: #111827;
- border-color: rgba(255,255,255,0.05);
+ border-color: rgba(255, 255, 255, 0.05);
}
/*
@@ -4538,7 +4979,7 @@ body.dark-theme .footer-bottom-links a {
}
body.dark-theme .section-eyebrow {
- background: rgba(255,255,255,0.08);
+ background: rgba(255, 255, 255, 0.08);
color: #a5b4fc;
}
@@ -4548,7 +4989,7 @@ body.dark-theme .stat-card,
body.dark-theme .step-card,
body.dark-theme .form-card {
background: #172033;
- border: 1px solid rgba(255,255,255,0.06);
+ border: 1px solid rgba(255, 255, 255, 0.06);
}
/*
@@ -4570,28 +5011,20 @@ body.dark-theme .feature-card h3 {
}
body.dark-theme .feature-card p {
- color: rgba(255,255,255,0.8);
+ color: rgba(255, 255, 255, 0.8);
}
-body.dark-theme .feature-card-link,
-[data-theme="dark"] .feature-card-link {
+body.dark-theme .feature-card-link {
background: rgba(255, 255, 255, 0.08);
color: white;
border-color: rgba(255, 255, 255, 0.14);
}
-body.dark-theme .feature-card-link:hover,
-[data-theme="dark"] .feature-card-link:hover {
- background: rgba(255, 255, 255, 0.16);
- border-color: rgba(255, 255, 255, 0.3);
- color: white;
-}
-
/*
ABOUT SECTION */
body.dark-theme .about-card {
background: #172033;
- border: 1px solid rgba(255,255,255,0.08);
+ border: 1px solid rgba(255, 255, 255, 0.08);
}
body.dark-theme .about-card h3,
@@ -4602,7 +5035,7 @@ body.dark-theme .about-card p {
/*
FORMS */
body.dark-theme label {
- color: rgba(255,255,255,0.9);
+ color: rgba(255, 255, 255, 0.9);
}
body.dark-theme input,
@@ -4611,24 +5044,24 @@ body.dark-theme textarea,
body.dark-theme .skill-input-wrap {
background: #111827;
color: white;
- border-color: rgba(255,255,255,0.08);
+ border-color: rgba(255, 255, 255, 0.08);
}
body.dark-theme input::placeholder,
body.dark-theme textarea::placeholder {
- color: rgba(255,255,255,0.45);
+ color: rgba(255, 255, 255, 0.45);
}
/* dropdown */
body.dark-theme .skills-suggestions {
background: #172033;
- border-color: rgba(255,255,255,0.08);
+ border-color: rgba(255, 255, 255, 0.08);
}
body.dark-theme .suggestion-item {
color: white;
- border-bottom-color: rgba(255,255,255,0.04);
+ border-bottom-color: rgba(255, 255, 255, 0.04);
}
body.dark-theme .suggestion-item:hover,
@@ -4639,12 +5072,12 @@ body.dark-theme .suggestion-item--active {
/* github button */
body.dark-theme #btn-show-github {
- background: rgba(255,255,255,0.08);
+ background: rgba(255, 255, 255, 0.08);
color: white;
}
body.dark-theme #btn-show-github:hover {
- background: rgba(255,255,255,0.14);
+ background: rgba(255, 255, 255, 0.14);
}
/*
@@ -4654,7 +5087,7 @@ body.dark-theme .footer {
}
body.dark-theme .footer-inner {
- border-color: rgba(255,255,255,0.06);
+ border-color: rgba(255, 255, 255, 0.06);
}
body.dark-theme .footer-links-list a:hover,
@@ -4666,11 +5099,11 @@ body.dark-theme .footer-bottom-links a:hover {
body.dark-theme .skill-strip-label,
body.dark-theme .ss-item {
- color: rgba(255,255,255,0.82);
+ color: rgba(255, 255, 255, 0.82);
}
body.dark-theme .ss-sep {
- background: rgba(255,255,255,0.22);
+ background: rgba(255, 255, 255, 0.22);
}
/*
@@ -4805,11 +5238,11 @@ body.dark-theme .theme-toggle:hover {
--text-body: var(--gray-600);
--text-light: var(--gray-400);
--border: var(--gray-200);
- --shadow-xs: 0 1px 2px rgba(0,0,0,0.3);
- --shadow-sm: 0 2px 8px rgba(0,0,0,0.4);
- --shadow-md: 0 4px 20px rgba(0,0,0,0.5);
- --shadow-lg: 0 8px 40px rgba(0,0,0,0.6);
- --shadow-xl: 0 16px 60px rgba(0,0,0,0.7);
+ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
+ --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4);
+ --shadow-md: 0 4px 20px rgba(0, 0, 0, 0.5);
+ --shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.6);
+ --shadow-xl: 0 16px 60px rgba(0, 0, 0, 0.7);
--indigo-100: #1a1f3a;
--indigo-50: #141830;
--purple-100: #1e1335;
@@ -5369,6 +5802,7 @@ body.dark-theme .theme-toggle:hover {
background: rgba(16, 185, 129, 0.15);
color: #6ee7b7;
}
+
/* Redesigned Stats Dashboard */
.stats-dashboard-grid {
display: grid;
@@ -5381,14 +5815,14 @@ body.dark-theme .theme-toggle:hover {
background: var(--card-bg);
border-radius: 1.25rem;
padding: 1.25rem;
- box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
border: 1px solid var(--border);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-dashboard-card:hover {
transform: translateY(-2px);
- box-shadow: 0 12px 24px -12px rgba(0,0,0,0.15);
+ box-shadow: 0 12px 24px -12px rgba(0, 0, 0, 0.15);
}
.stat-dashboard-header {
@@ -5646,12 +6080,12 @@ body.dark-theme .theme-toggle:hover {
grid-template-columns: 1fr;
gap: 1rem;
}
-
+
.profile-bottom-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
-
+
.activity-stats-row {
grid-template-columns: repeat(4, 1fr);
}
@@ -5675,70 +6109,5 @@ body.dark-theme .theme-toggle:hover {
color: #c4b5fd;
}
-.project-match-explanation {
- display: flex;
- align-items: flex-start;
- gap: 6px;
- font-size: 0.85rem;
- color: var(--text-color);
- opacity: 0.85;
- background: var(--bg-hover);
- padding: 10px 12px;
- border-radius: 6px;
- border-left: 3px solid var(--primary-color);
- margin-top: 15px;
- margin-bottom: 15px;
- line-height: 1.4;
-}
-.explanation-icon {
- flex-shrink: 0;
- margin-top: 2px;
- color: var(--primary-color);
-}
-
-.project-match-score {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-bottom: 10px;
- font-size: 0.8rem;
-}
-.score-label {
- font-weight: 600;
- color: var(--text-body);
- white-space: nowrap;
-}
-.score-value {
- font-weight: 700;
- color: var(--accent);
- white-space: nowrap;
-}
-.score-bar {
- flex: 1;
- height: 6px;
- background: var(--border);
- border-radius: 3px;
- overflow: hidden;
-}
-.score-bar-fill {
- height: 100%;
- background: var(--accent);
- border-radius: 3px;
- transition: width 0.4s ease;
-}
-
-/* Surprise Me Button Styling */
-.btn-surprise {
- background-color: #6b21a8;
- color: #ffffff;
- padding: 0.5rem 1rem;
- border: none;
- border-radius: 0.375rem;
- font-weight: 600;
- cursor: pointer;
- transition: background-color 0.2s ease-in-out;
- margin-left: 0.5rem;
-}
-.btn-surprise:hover {
- background-color: #581c87;
-}
+/* ========================================
+ SKILLS SECTION - LIGHT & DARK THEME
diff --git a/src/templates/index.html b/src/templates/index.html
index 7098c8fe..cddca091 100644
--- a/src/templates/index.html
+++ b/src/templates/index.html
@@ -7,9 +7,9 @@
DevPath — Find Projects Based On Your Skills
-
+
+
{% include 'partials/theme_head.html' %}
@@ -62,13 +63,13 @@
-
+