diff --git a/web-app/css/styles.css b/web-app/css/styles.css index 077b3d7c..10dbdf3b 100644 --- a/web-app/css/styles.css +++ b/web-app/css/styles.css @@ -1299,48 +1299,149 @@ main>.hero-section:has(.hero-code-snippets) { } -/* ── Hero Meta ─────────────────────────────────────────────── */ -.hero-meta { +/* ── Stats Dashboard ───────────────────────────────────────── */ +.stats-dashboard { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 1rem; + width: 100%; + max-width: 1200px; + margin: 2rem auto 0; + padding: 0 1rem; + box-sizing: border-box; +} + +.stats-card { display: flex; - gap: 0.8rem; - flex-wrap: wrap; + flex-direction: column; + align-items: center; justify-content: center; - font-family: var(--font-mono); - font-size: 0.78rem; - color: var(--text-secondary); - margin: 1.25rem 0 0; + background: rgba(255, 255, 255, 0.45); + backdrop-filter: blur(16px); + -webkit-backdrop-filter: blur(16px); + border: 1px solid rgba(255, 255, 255, 0.5); + border-radius: 16px; + padding: 1.25rem 1rem; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); + box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.05); + outline: none; + font-family: inherit; + color: inherit; + box-sizing: border-box; } -.hero-meta span { - padding: 0.6rem 0.95rem; - border-radius: 12px; - background: rgba(255, 255, 255, 0.78); - border: 1px solid rgba(128, 104, 85, 0.08); - font-size: 0.82rem; - box-shadow: 0 2px 6px rgba(146, 111, 74, 0.04); - display: inline-flex; - align-items: center; - gap: 0.45rem; +[data-theme="dark"] .stats-card { + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37); } -.hero-meta strong { - color: var(--text); - font-weight: 600; +/* Hover and focus styles */ +.stats-card:hover, +.stats-card:focus-visible { + transform: translateY(-5px) scale(1.03); + background: rgba(255, 255, 255, 0.6); + border-color: rgba(34, 197, 94, 0.5); /* Glowing green border on hover */ + box-shadow: 0 0 15px rgba(34, 197, 94, 0.3), 0 12px 40px rgba(31, 38, 135, 0.08); } -.hero-meta span::before { - content: ""; - width: 4px; - height: 4px; +[data-theme="dark"] .stats-card:hover, +[data-theme="dark"] .stats-card:focus-visible { + background: rgba(255, 255, 255, 0.07); + border-color: rgba(74, 222, 128, 0.6); /* Green glowing border in dark mode */ + box-shadow: 0 0 20px rgba(74, 222, 128, 0.3), 0 12px 40px rgba(0, 0, 0, 0.5); +} + +/* Active/selected state filter highlight */ +.stats-card.active { + background: rgba(255, 255, 255, 0.7); + border-color: rgba(34, 197, 94, 0.8); + box-shadow: 0 0 20px rgba(34, 197, 94, 0.4), 0 8px 24px rgba(31, 38, 135, 0.06); +} + +[data-theme="dark"] .stats-card.active { + background: rgba(255, 255, 255, 0.09); + border-color: rgba(74, 222, 128, 0.9); + box-shadow: 0 0 25px rgba(74, 222, 128, 0.5), 0 8px 24px rgba(0, 0, 0, 0.4); +} + +/* Accents and text elements */ +.stats-icon { + margin-bottom: 0.75rem; + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; border-radius: 50%; - background: var(--accent); - opacity: 0.6; + background: rgba(34, 197, 94, 0.1); + color: #22c55e; + transition: transform 0.3s ease; } -[data-theme="dark"] .hero-meta span { - background: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 239, 223, 0.1); - box-shadow: none; +[data-theme="dark"] .stats-icon { + background: rgba(74, 222, 128, 0.15); + color: #4ade80; +} + +.stats-icon svg { + width: 20px; + height: 20px; + stroke-width: 2.25; +} + +.stats-card:hover .stats-icon { + transform: rotate(8deg) scale(1.1); +} + +.stats-info { + display: flex; + flex-direction: column; + align-items: center; +} + +/* customized green accents for metrics counters */ +.stats-info strong { + font-size: 1.75rem; + font-weight: 700; + line-height: 1.2; + color: #166534; /* customized dark-green accent */ + transition: all 0.3s ease; +} + +[data-theme="dark"] .stats-info strong { + color: #4ade80; /* customized light-green/neon accent for dark mode */ +} + +.stats-info span { + font-size: 0.8rem; + font-weight: 500; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; + margin-top: 0.25rem; + text-align: center; +} + +@media (max-width: 1024px) { + .stats-dashboard { + grid-template-columns: repeat(3, 1fr); + gap: 1rem; + } +} + +@media (max-width: 640px) { + .stats-dashboard { + grid-template-columns: repeat(2, 1fr); + gap: 0.75rem; + } +} + +@media (max-width: 400px) { + .stats-dashboard { + grid-template-columns: 1fr; + } } diff --git a/web-app/index.html b/web-app/index.html index c43f5527..baba1313 100644 --- a/web-app/index.html +++ b/web-app/index.html @@ -237,17 +237,61 @@

-
-
- 0 total projects - 0 games - 0 maths - 0 utilities -
-
- 0Favorites - 0Recently Viewed -
+
+ + + + + +
@@ -1011,7 +1055,7 @@

${proj.title}

animateCounter("statsGames",games); animateCounter("statsMath",math); animateCounter("statsUtilities",utils); -const viewed= JSON.parse(localStorage.getItem("recentlyViewed")||"[]"); +const viewed= JSON.parse(localStorage.getItem("recentProjects")||"[]"); animateCounter("heroViewedCount",viewed.length); console.log( diff --git a/web-app/js/main.js b/web-app/js/main.js index 7ae8eeb6..ab1c08cb 100644 --- a/web-app/js/main.js +++ b/web-app/js/main.js @@ -588,6 +588,13 @@ document.addEventListener("DOMContentLoaded", function () { currentCategory = category; syncSidebarTabs(category); syncStickyTabs(category); + + // Sync stats cards highlight + var statsCards = document.querySelectorAll(".stats-card"); + statsCards.forEach(function (card) { + card.classList.toggle("active", card.getAttribute("data-filter") === category); + }); + var visibleCount = 0; var favorites = JSON.parse(localStorage.getItem("favorites") || "[]"); projectCards.forEach(function (card) { @@ -647,6 +654,10 @@ document.addEventListener("DOMContentLoaded", function () { function showPlaygroundSection() { playgroundActive = true; syncStickyTabs("playground"); + var statsCards = document.querySelectorAll(".stats-card"); + statsCards.forEach(function (card) { + card.classList.remove("active"); + }); if (projectsSection) projectsSection.style.display = "none"; if (playgroundSection) { playgroundSection.style.display = ""; @@ -766,6 +777,35 @@ document.addEventListener("DOMContentLoaded", function () { }); }); + /* ── Stats Cards ──────────────────────────────────────────── */ + var statsCards = document.querySelectorAll(".stats-card"); + statsCards.forEach(function (card) { + card.addEventListener("click", function () { + var category = card.getAttribute("data-filter"); + + // Update active highlight class on stats cards + statsCards.forEach(function (c) { + c.classList.toggle("active", c === card); + }); + + if (category === "recent") { + var section = document.getElementById("recentlyViewedSection"); + if (section) { + section.scrollIntoView({ behavior: "smooth", block: "start" }); + } + } else { + showProjectsSection(); + applyCategoryFilter(category); + if (projectsSection) { + projectsSection.scrollIntoView({ + behavior: "smooth", + block: "start", + }); + } + } + }); + }); + /* ── Sticky Filter Bar Visibility ─────────────────────────── */ if (stickyFilterBar && heroSection) { var heroObserver = new IntersectionObserver( @@ -1793,11 +1833,13 @@ card.appendChild(badge); const historyBadge = document.getElementById("historyCountBadge"); -if(historyBadge){ - -historyBadge.textContent=`(${recent.length})`; - -} + if(historyBadge){ + historyBadge.textContent=`(${recent.length})`; + } + const heroViewedCount = document.getElementById("heroViewedCount"); + if (heroViewedCount) { + heroViewedCount.textContent = String(recent.length); + } console.log("[DEBUG] recentProjects array:", recent); if (recent.length === 0) { section.style.display = "none"; return;