From d3062df4db795c0c77f517b23568c7220527b1bf Mon Sep 17 00:00:00 2001 From: shashank Date: Sun, 17 May 2026 11:07:38 +0530 Subject: [PATCH] Add dark mode feature --- static/script.js | 58 +- static/style.css | 1285 ++++++++++++++++++++++++++++++++++-------- templates/index.html | 162 +++--- 3 files changed, 1173 insertions(+), 332 deletions(-) diff --git a/static/script.js b/static/script.js index 5bf5aa2f..3586304c 100644 --- a/static/script.js +++ b/static/script.js @@ -12,7 +12,7 @@ // Detect which page we are on // ============================================================ // !! trick turns the DOM result into a simple true/false -var isIndexPage = !!document.getElementById("recommend-form"); +var isIndexPage = !!document.getElementById("recommend-form"); // PROJECT_ID is set by the server only on detail pages, so if it's missing we're elsewhere var isDetailPage = typeof PROJECT_ID !== "undefined"; @@ -85,7 +85,7 @@ if (isIndexPage) { "C#", "Ruby", "PHP", "Go", "Swift", "TypeScript", "Angular", "Vue.js", "Spring", "Flutter", "TensorFlow", "PyTorch", "Data Science", "Machine Learning", "Artificial Intelligence", "DevOps", "Cybersecurity", - "Blockchain", "UI/UX Design", "Game Development", "CI/CD", "REST API", "GraphQL", + "Blockchain", "UI/UX Design", "Game Development", "CI/CD", "REST API", "GraphQL", "Rust", "Kotlin" ]; } @@ -413,10 +413,10 @@ if (isIndexPage) { var payload = { // Prefer the hidden input value; fall back to raw text box if hidden input is empty - skills: skillsHidden.value.trim() || skillsTextInput.value.trim(), - level: document.getElementById("level").value, + skills: skillsHidden.value.trim() || skillsTextInput.value.trim(), + level: document.getElementById("level").value, interest: document.getElementById("interest").value, - time: document.getElementById("time").value + time: document.getElementById("time").value }; fetch("/api/recommend", { @@ -636,21 +636,21 @@ if (isDetailPage) { // ---------------------------------------------------------- // Copy Code button // ---------------------------------------------------------- - var btnCopyCode = document.getElementById("btn-copy-code"); - var copyToast = document.getElementById("copy-toast"); + var btnCopyCode = document.getElementById("btn-copy-code"); + var copyToast = document.getElementById("copy-toast"); var toastTimeout = null; function showCopySuccess() { if (!btnCopyCode) return; // Swap icons on the button - var copyIcon = btnCopyCode.querySelector(".copy-icon"); + var copyIcon = btnCopyCode.querySelector(".copy-icon"); var checkIcon = btnCopyCode.querySelector(".check-icon"); - var btnLabel = btnCopyCode.querySelector(".copy-btn-label"); + var btnLabel = btnCopyCode.querySelector(".copy-btn-label"); - if (copyIcon) copyIcon.style.display = "none"; + if (copyIcon) copyIcon.style.display = "none"; if (checkIcon) checkIcon.style.display = "inline"; - if (btnLabel) btnLabel.textContent = "Copied!"; + if (btnLabel) btnLabel.textContent = "Copied!"; btnCopyCode.classList.add("copied"); // Disable button so user can't spam click it while toast is showing btnCopyCode.disabled = true; @@ -664,9 +664,9 @@ if (isDetailPage) { // Clear any previous timeout first so timers don't stack up clearTimeout(toastTimeout); toastTimeout = setTimeout(function () { - if (copyIcon) copyIcon.style.display = "inline"; + if (copyIcon) copyIcon.style.display = "inline"; if (checkIcon) checkIcon.style.display = "none"; - if (btnLabel) btnLabel.textContent = "Copy Code"; + if (btnLabel) btnLabel.textContent = "Copy Code"; btnCopyCode.classList.remove("copied"); btnCopyCode.disabled = false; if (copyToast) copyToast.classList.remove("show"); @@ -704,4 +704,34 @@ if (isDetailPage) { document.body.removeChild(ta); } -} // end isDetailPage \ No newline at end of file +} // end isDetailPage + +//dark mode toggle (runs on all pages) +const themeToggle = + document.getElementById("theme-toggle"); + +const savedTheme = + localStorage.getItem("theme"); + +if (savedTheme === "dark") { + document.body.classList.add("dark-mode"); + themeToggle.innerHTML = "Light"; +} + +themeToggle.addEventListener("click", () => { + + document.body.classList.toggle("dark-mode"); + + if (document.body.classList.contains("dark-mode")) { + + localStorage.setItem("theme", "dark"); + + themeToggle.innerHTML = "Light"; + + } else { + + localStorage.setItem("theme", "light"); + + themeToggle.innerHTML = "Dark"; + } +}); \ No newline at end of file diff --git a/static/style.css b/static/style.css index ad19d108..a94819c9 100644 --- a/static/style.css +++ b/static/style.css @@ -14,7 +14,7 @@ --indigo-600: #3347e0; --indigo-500: #4f6ef7; --indigo-100: #eef1ff; - --indigo-50: #f5f7ff; + --indigo-50: #f5f7ff; --purple-700: #5b21b6; --purple-600: #7c3aed; @@ -24,32 +24,32 @@ --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; - --gray-100: #f3f4f6; - --gray-200: #e5e7eb; - --gray-300: #d1d5db; - --gray-400: #9ca3af; - --gray-500: #6b7280; - --gray-600: #4b5563; - --gray-700: #374151; - --gray-900: #111827; + --white: #ffffff; + --gray-50: #f9fafb; + --gray-100: #f3f4f6; + --gray-200: #e5e7eb; + --gray-300: #d1d5db; + --gray-400: #9ca3af; + --gray-500: #6b7280; + --gray-600: #4b5563; + --gray-700: #374151; + --gray-900: #111827; /* Semantic */ --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); /* Shadows */ --shadow-xs: 0 1px 2px rgba(15, 21, 96, 0.05); @@ -59,25 +59,35 @@ --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; /* Fonts */ --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; /* Transition */ --t: 0.2s ease; } /* ---- Reset ------------------------------------------------- */ -*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } -html { scroll-behavior: smooth; } +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + scroll-behavior: smooth; +} + body { font-family: var(--font-body); color: var(--gray-700); @@ -85,10 +95,25 @@ body { line-height: 1.65; -webkit-font-smoothing: antialiased; } -img { display: block; max-width: 100%; } -a { color: var(--indigo-500); text-decoration: none; } -a:hover { text-decoration: underline; } -ul, ol { list-style: none; } + +img { + display: block; + max-width: 100%; +} + +a { + color: var(--indigo-500); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +ul, +ol { + list-style: none; +} /* ---- Shared utilities -------------------------------------- */ .container { @@ -131,12 +156,14 @@ ul, ol { list-style: none; } /* ---- Navigation ------------------------------------------- */ .navbar { position: fixed; - top: 0; left: 0; right: 0; + top: 0; + left: 0; + right: 0; z-index: 200; background: rgba(10, 15, 100, 0.88); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); - border-bottom: 1px solid rgba(255,255,255,0.06); + border-bottom: 1px solid rgba(255, 255, 255, 0.06); transition: background var(--t); } @@ -157,31 +184,46 @@ ul, ol { list-style: none; } color: var(--white); letter-spacing: -0.04em; } -.nav-logo:hover { text-decoration: none; } -.nav-logo-accent { color: var(--yellow-400); } -.nav-links { display: flex; align-items: center; gap: 32px; } +.nav-logo:hover { + text-decoration: none; +} + +.nav-logo-accent { + color: var(--yellow-400); +} + +.nav-links { + display: flex; + align-items: center; + gap: 32px; +} .nav-link { font-size: 0.88rem; font-weight: 500; - color: rgba(255,255,255,0.7); + color: rgba(255, 255, 255, 0.7); transition: color var(--t); } -.nav-link:hover { color: var(--white); text-decoration: none; } + +.nav-link:hover { + color: var(--white); + text-decoration: none; +} .nav-btn-outline { font-size: 0.86rem; font-weight: 600; - color: rgba(255,255,255,0.85); - border: 1.5px solid rgba(255,255,255,0.28); + color: rgba(255, 255, 255, 0.85); + border: 1.5px solid rgba(255, 255, 255, 0.28); border-radius: var(--r-full); padding: 7px 18px; transition: background var(--t), border-color var(--t); } + .nav-btn-outline:hover { - background: rgba(255,255,255,0.1); - border-color: rgba(255,255,255,0.45); + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.45); text-decoration: none; } @@ -195,6 +237,7 @@ ul, ol { list-style: none; } cursor: pointer; padding: 4px; } + .nav-mobile-toggle span { display: block; width: 22px; @@ -203,27 +246,47 @@ ul, ol { list-style: none; } border-radius: 2px; transition: transform var(--t), opacity var(--t); } -.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); } + +.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); +} .nav-mobile-menu { display: none; flex-direction: column; padding: 16px 32px 20px; background: var(--indigo-900); - border-top: 1px solid rgba(255,255,255,0.06); + border-top: 1px solid rgba(255, 255, 255, 0.06); +} + +.nav-mobile-menu.open { + display: flex; } -.nav-mobile-menu.open { display: flex; } + .nav-mobile-link { font-size: 0.95rem; font-weight: 500; - color: rgba(255,255,255,0.8); + color: rgba(255, 255, 255, 0.8); padding: 10px 0; - border-bottom: 1px solid rgba(255,255,255,0.06); + border-bottom: 1px solid rgba(255, 255, 255, 0.06); +} + +.nav-mobile-link:hover { + color: var(--white); + text-decoration: none; +} + +.nav-mobile-link:last-child { + border-bottom: none; } -.nav-mobile-link:hover { color: var(--white); text-decoration: none; } -.nav-mobile-link:last-child { border-bottom: none; } /* ---- Hero Section ----------------------------------------- */ .hero { @@ -240,7 +303,7 @@ ul, ol { list-style: none; } .hero-bg-grid { position: absolute; inset: 0; - background-image: radial-gradient(rgba(255,255,255,0.06) 1px, transparent 1px); + background-image: radial-gradient(rgba(255, 255, 255, 0.06) 1px, transparent 1px); background-size: 28px 28px; pointer-events: none; } @@ -258,7 +321,10 @@ ul, ol { list-style: none; } } /* Copy column (order keeps layout when decorative blocks follow in DOM) */ -.hero-copy { max-width: 580px; order: 1; } +.hero-copy { + max-width: 580px; + order: 1; +} .hero-badge { display: inline-flex; @@ -268,15 +334,17 @@ ul, ol { list-style: none; } font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; - color: rgba(255,255,255,0.75); - border: 1px solid rgba(255,255,255,0.2); - background: rgba(255,255,255,0.07); + color: rgba(255, 255, 255, 0.75); + border: 1px solid rgba(255, 255, 255, 0.2); + background: rgba(255, 255, 255, 0.07); border-radius: var(--r-full); padding: 6px 16px; margin-bottom: 24px; } + .hero-badge-dot { - width: 7px; height: 7px; + width: 7px; + height: 7px; border-radius: 50%; background: var(--green-500); box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.25); @@ -291,11 +359,14 @@ ul, ol { list-style: none; } letter-spacing: -0.04em; margin-bottom: 22px; } -.hero-heading-accent { color: var(--yellow-300); } + +.hero-heading-accent { + color: var(--yellow-300); +} .hero-subtext { font-size: 1.08rem; - color: rgba(255,255,255,0.72); + color: rgba(255, 255, 255, 0.72); line-height: 1.78; margin-bottom: 32px; max-width: 500px; @@ -308,7 +379,11 @@ ul, ol { list-style: none; } gap: 24px; margin-bottom: 36px; } -.hero-stat { text-align: center; } + +.hero-stat { + text-align: center; +} + .hero-stat-num { display: block; font-family: var(--font-display); @@ -317,19 +392,26 @@ ul, ol { list-style: none; } color: var(--white); letter-spacing: -0.03em; } + .hero-stat-label { font-size: 0.77rem; - color: rgba(255,255,255,0.55); + color: rgba(255, 255, 255, 0.55); letter-spacing: 0.04em; } + .hero-stat-divider { width: 1px; height: 36px; - background: rgba(255,255,255,0.15); + background: rgba(255, 255, 255, 0.15); } /* Hero CTA buttons */ -.hero-cta-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; } +.hero-cta-row { + display: flex; + align-items: center; + gap: 14px; + flex-wrap: wrap; +} .btn-hero-primary { display: inline-flex; @@ -345,6 +427,7 @@ ul, ol { list-style: none; } box-shadow: 0 4px 20px rgba(251, 191, 36, 0.4); transition: background var(--t), transform var(--t), box-shadow var(--t); } + .btn-hero-primary:hover { background: var(--yellow-300); transform: translateY(-2px); @@ -357,8 +440,8 @@ ul, ol { list-style: none; } align-items: center; gap: 8px; padding: 14px 28px; - background: rgba(255,255,255,0.1); - border: 1.5px solid rgba(255,255,255,0.25); + background: rgba(255, 255, 255, 0.1); + border: 1.5px solid rgba(255, 255, 255, 0.25); color: var(--white); font-family: var(--font-display); font-size: 0.95rem; @@ -366,7 +449,11 @@ ul, ol { list-style: none; } border-radius: var(--r-full); transition: background var(--t); } -.btn-hero-ghost:hover { background: rgba(255,255,255,0.18); text-decoration: none; } + +.btn-hero-ghost:hover { + background: rgba(255, 255, 255, 0.18); + text-decoration: none; +} /* Visual column (code preview cards) */ .hero-visual { @@ -382,22 +469,49 @@ ul, ol { list-style: none; } display: flex; align-items: center; gap: 14px; - background: rgba(255,255,255,0.95); + background: rgba(255, 255, 255, 0.95); border-radius: var(--r-md); padding: 14px 18px; box-shadow: var(--shadow-lg); } + .hvc-icon { - width: 40px; height: 40px; + width: 40px; + height: 40px; border-radius: var(--r-sm); - display: flex; align-items: center; justify-content: center; + display: flex; + align-items: center; + justify-content: center; flex-shrink: 0; } -.hvc-icon--blue { background: var(--indigo-100); color: var(--indigo-600); } -.hvc-icon--green { background: var(--green-100); color: var(--green-500); } -.hvc-text { display: flex; flex-direction: column; gap: 2px; } -.hvc-title { font-family: var(--font-display); font-size: 0.88rem; font-weight: 700; color: var(--gray-900); } -.hvc-sub { font-size: 0.77rem; color: var(--gray-500); } + +.hvc-icon--blue { + background: var(--indigo-100); + color: var(--indigo-600); +} + +.hvc-icon--green { + background: var(--green-100); + color: var(--green-500); +} + +.hvc-text { + display: flex; + flex-direction: column; + gap: 2px; +} + +.hvc-title { + font-family: var(--font-display); + font-size: 0.88rem; + font-weight: 700; + color: var(--gray-900); +} + +.hvc-sub { + font-size: 0.77rem; + color: var(--gray-500); +} /* Code preview card */ .hero-visual-main { @@ -406,19 +520,41 @@ ul, ol { list-style: none; } overflow: hidden; box-shadow: var(--shadow-xl); } + .hvm-header { display: flex; align-items: center; gap: 6px; padding: 10px 16px; background: #161b22; - border-bottom: 1px solid rgba(255,255,255,0.05); + border-bottom: 1px solid rgba(255, 255, 255, 0.05); +} + +.hvm-dot { + width: 11px; + height: 11px; + border-radius: 50%; + flex-shrink: 0; +} + +.hvm-dot--red { + background: #ff5f56; +} + +.hvm-dot--yellow { + background: #ffbd2e; +} + +.hvm-dot--green { + background: #27c93f; +} + +.hvm-filename { + font-family: var(--font-mono); + font-size: 0.75rem; + color: rgba(255, 255, 255, 0.35); + margin-left: 6px; } -.hvm-dot { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; } -.hvm-dot--red { background: #ff5f56; } -.hvm-dot--yellow { background: #ffbd2e; } -.hvm-dot--green { background: #27c93f; } -.hvm-filename { font-family: var(--font-mono); font-size: 0.75rem; color: rgba(255,255,255,0.35); margin-left: 6px; } .hvm-code { padding: 18px 20px; @@ -429,13 +565,35 @@ ul, ol { list-style: none; } font-size: 0.8rem; line-height: 1.85; } -.hvm-line { display: block; color: #e6edf3; } -.hvm-indent { padding-left: 20px; } -.hvm-indent2 { padding-left: 40px; } -.hvm-kw { color: #ff7b72; } -.hvm-fn { color: #d2a8ff; } -.hvm-cm { color: #8b949e; } -.hvm-op { color: #79c0ff; } + +.hvm-line { + display: block; + color: #e6edf3; +} + +.hvm-indent { + padding-left: 20px; +} + +.hvm-indent2 { + padding-left: 40px; +} + +.hvm-kw { + color: #ff7b72; +} + +.hvm-fn { + color: #d2a8ff; +} + +.hvm-cm { + color: #8b949e; +} + +.hvm-op { + color: #79c0ff; +} /* Hero decorative blobs */ .hero-blob { @@ -445,15 +603,21 @@ ul, ol { list-style: none; } filter: blur(90px); opacity: 0.25; } + .hero-blob-1 { - width: 560px; height: 560px; + width: 560px; + height: 560px; background: var(--purple-600); - top: -180px; right: -180px; + top: -180px; + right: -180px; } + .hero-blob-2 { - width: 360px; height: 360px; + width: 360px; + height: 360px; background: var(--indigo-500); - bottom: -80px; left: -100px; + bottom: -80px; + left: -100px; } /* ---- Skill Strip ------------------------------------------ */ @@ -463,6 +627,7 @@ ul, ol { list-style: none; } border-bottom: 1px solid var(--border); padding: 18px 32px; } + .skill-strip-inner { max-width: 1140px; margin: 0 auto; @@ -471,6 +636,7 @@ ul, ol { list-style: none; } gap: 20px; flex-wrap: wrap; } + .skill-strip-label { font-size: 0.8rem; font-weight: 600; @@ -479,18 +645,21 @@ ul, ol { list-style: none; } text-transform: uppercase; white-space: nowrap; } + .skill-strip-items { display: flex; align-items: center; flex-wrap: wrap; gap: 0; } + .ss-item { font-size: 0.88rem; font-weight: 600; color: var(--gray-700); padding: 0 16px; } + .ss-sep { width: 1px; height: 16px; @@ -524,7 +693,11 @@ ul, ol { list-style: none; } box-shadow: var(--shadow-sm); transition: box-shadow var(--t), transform var(--t); } -.step-card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px); } + +.step-card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-3px); +} .step-num { font-family: var(--font-display); @@ -546,7 +719,12 @@ ul, ol { list-style: none; } color: var(--text-heading); margin-bottom: 10px; } -.step-card p { font-size: 0.9rem; color: var(--text-body); line-height: 1.65; } + +.step-card p { + font-size: 0.9rem; + color: var(--text-body); + line-height: 1.65; +} .step-connector { color: var(--gray-300); @@ -578,23 +756,47 @@ ul, ol { list-style: none; } overflow: hidden; transition: transform var(--t), box-shadow var(--t); } -.feature-card:hover { transform: translateY(-5px); 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:hover { + transform: translateY(-5px); + 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-icon { - width: 52px; height: 52px; - background: rgba(255,255,255,0.7); + width: 52px; + height: 52px; + background: rgba(255, 255, 255, 0.7); border-radius: var(--r-sm); - display: flex; align-items: center; justify-content: center; + display: flex; + align-items: center; + justify-content: center; margin-bottom: 22px; 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); @@ -603,6 +805,7 @@ ul, ol { list-style: none; } color: var(--text-heading); margin-bottom: 12px; } + .feature-card p { font-size: 0.91rem; color: var(--gray-600); @@ -618,11 +821,12 @@ ul, ol { list-style: none; } font-weight: 700; color: var(--indigo-700); border: 1.5px solid var(--indigo-200, #c7d2fe); - background: rgba(255,255,255,0.6); + background: rgba(255, 255, 255, 0.6); padding: 7px 16px; border-radius: var(--r-full); transition: background var(--t), border-color var(--t); } + .feature-card-link:hover { background: var(--white); border-color: var(--indigo-500); @@ -651,7 +855,9 @@ ul, ol { list-style: none; } } /* Form groups */ -.form-group { margin-bottom: 24px; } +.form-group { + margin-bottom: 24px; +} .form-row { display: grid; @@ -683,6 +889,7 @@ label { cursor: text; transition: border-color var(--t), box-shadow var(--t); } + .skill-input-wrap:focus-within { border-color: var(--indigo-500); box-shadow: 0 0 0 3px rgba(79, 110, 247, 0.12); @@ -709,6 +916,7 @@ label { border-radius: var(--r-full); padding: 3px 10px 3px 12px; } + .skill-chip-remove { background: none; border: none; @@ -721,7 +929,10 @@ label { align-items: center; transition: color var(--t); } -.skill-chip-remove:hover { color: var(--red-500); } + +.skill-chip-remove:hover { + color: var(--red-500); +} /* Text input inside the skill wrap */ .skill-input-wrap input[type="text"] { @@ -735,6 +946,7 @@ label { font-size: 0.93rem; color: var(--gray-900); } + .skill-input-wrap input[type="text"]:focus { outline: none; box-shadow: none; @@ -816,27 +1028,35 @@ label { cursor: pointer; transition: background var(--t), border-color var(--t), color var(--t); } -.skill-chip:hover, .skill-chip.active { + +.skill-chip:hover, +.skill-chip.active { background: var(--indigo-700); border-color: var(--indigo-700); color: var(--white); } /* Select wrapper with custom chevron */ -.select-wrap { position: relative; } +.select-wrap { + position: relative; +} + .select-wrap::after { content: ""; position: absolute; - right: 14px; top: 50%; + right: 14px; + top: 50%; transform: translateY(-50%); - width: 0; height: 0; + width: 0; + height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid var(--gray-400); pointer-events: none; } -select, input[type="text"]:not(.skill-input-wrap input) { +select, +input[type="text"]:not(.skill-input-wrap input) { width: 100%; padding: 11px 14px; border: 1.5px solid var(--border); @@ -849,6 +1069,7 @@ select, input[type="text"]:not(.skill-input-wrap input) { -webkit-appearance: none; transition: border-color var(--t), box-shadow var(--t); } + select:focus { outline: none; border-color: var(--indigo-500); @@ -863,6 +1084,7 @@ select:focus { color: var(--gray-400); margin-top: 5px; } + .form-error-msg { font-size: 0.81rem; color: var(--red-500); @@ -870,6 +1092,7 @@ select:focus { min-height: 18px; font-weight: 500; } + .form-error-general { font-size: 0.84rem; color: var(--red-500); @@ -895,12 +1118,19 @@ select:focus { transition: opacity var(--t), transform var(--t), box-shadow var(--t); margin-top: 8px; } + .btn-submit:hover { opacity: 0.93; transform: translateY(-1px); box-shadow: 0 6px 28px rgba(35, 53, 194, 0.42); } -.btn-submit:disabled { opacity: 0.55; cursor: not-allowed; transform: none; box-shadow: none; } + +.btn-submit:disabled { + opacity: 0.55; + cursor: not-allowed; + transform: none; + box-shadow: none; +} /* ---- Results Section -------------------------------------- */ .results-section { @@ -913,30 +1143,55 @@ select:focus { padding: 56px 0; color: var(--text-body); } + .loading-dots { display: flex; justify-content: center; gap: 8px; margin-bottom: 18px; } + .loading-dots span { - width: 11px; height: 11px; + width: 11px; + height: 11px; background: var(--indigo-500); border-radius: 50%; 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% { transform: scale(0.6); opacity: 0.4; } - 40% { transform: scale(1.1); opacity: 1; } + + 0%, + 80%, + 100% { + transform: scale(0.6); + opacity: 0.4; + } + + 40% { + transform: scale(1.1); + opacity: 1; + } } /* Empty state */ .empty-state { padding: 64px 0 32px; } -.empty-icon { color: var(--gray-300); margin-bottom: 20px; } + +.empty-icon { + color: var(--gray-300); + margin-bottom: 20px; +} + .empty-state h3 { font-family: var(--font-display); font-size: 1.3rem; @@ -944,7 +1199,12 @@ select:focus { color: var(--text-heading); margin-bottom: 10px; } -.empty-state p { color: var(--text-body); margin-bottom: 24px; } + +.empty-state p { + color: var(--text-body); + margin-bottom: 24px; +} + .btn-try-again { padding: 11px 24px; background: var(--indigo-100); @@ -957,7 +1217,10 @@ select:focus { cursor: pointer; transition: background var(--t); } -.btn-try-again:hover { background: var(--indigo-100); } + +.btn-try-again:hover { + background: var(--indigo-100); +} /* Results grid */ .results-grid { @@ -980,6 +1243,7 @@ select:focus { gap: 16px; transition: box-shadow var(--t), transform var(--t), border-color var(--t); } + .project-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-5px); @@ -992,6 +1256,7 @@ select:focus { font-weight: 700; color: var(--text-heading); } + .project-card-desc { font-size: 0.88rem; color: var(--text-body); @@ -1004,22 +1269,44 @@ select:focus { flex-wrap: wrap; gap: 7px; } + .project-tag { font-size: 0.74rem; font-weight: 600; padding: 3px 11px; border-radius: var(--r-full); } -.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-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 { padding-top: 8px; border-top: 1px solid var(--gray-100); } + .btn-details { display: block; width: 100%; @@ -1036,6 +1323,7 @@ select:focus { transition: background var(--t), color var(--t); text-decoration: none; } + .btn-details:hover { background: var(--indigo-600); color: var(--white); @@ -1048,6 +1336,7 @@ select:focus { background: linear-gradient(135deg, var(--indigo-800) 0%, var(--purple-700) 100%); text-align: center; } + .cta-inner h2 { font-family: var(--font-display); font-size: clamp(2rem, 4vw, 3rem); @@ -1057,12 +1346,17 @@ select:focus { line-height: 1.2; margin-bottom: 14px; } -.cta-accent { color: var(--yellow-300); } + +.cta-accent { + color: var(--yellow-300); +} + .cta-inner p { font-size: 1.05rem; - color: rgba(255,255,255,0.72); + color: rgba(255, 255, 255, 0.72); margin-bottom: 36px; } + .btn-cta { display: inline-flex; align-items: center; @@ -1077,6 +1371,7 @@ select:focus { box-shadow: 0 6px 24px rgba(251, 191, 36, 0.45); transition: background var(--t), transform var(--t); } + .btn-cta:hover { background: var(--yellow-300); transform: translateY(-2px); @@ -1088,6 +1383,7 @@ select:focus { background: var(--indigo-900); padding: 64px 32px 0; } + .footer-inner { max-width: 1140px; margin: 0 auto; @@ -1095,8 +1391,9 @@ select:focus { grid-template-columns: 2fr 1fr 1fr 1fr; gap: 40px; padding-bottom: 56px; - border-bottom: 1px solid rgba(255,255,255,0.08); + border-bottom: 1px solid rgba(255, 255, 255, 0.08); } + .footer-logo { font-family: var(--font-display); font-size: 1.3rem; @@ -1106,24 +1403,43 @@ select:focus { display: block; margin-bottom: 14px; } -.footer-logo-accent { color: var(--yellow-400); } -.footer-tagline { font-size: 0.86rem; color: rgba(255,255,255,0.45); line-height: 1.7; } + +.footer-logo-accent { + color: var(--yellow-400); +} + +.footer-tagline { + font-size: 0.86rem; + color: rgba(255, 255, 255, 0.45); + line-height: 1.7; +} + .footer-col-title { font-family: var(--font-display); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; - color: rgba(255,255,255,0.45); + color: rgba(255, 255, 255, 0.45); margin-bottom: 18px; } -.footer-links-list { display: flex; flex-direction: column; gap: 10px; } + +.footer-links-list { + display: flex; + flex-direction: column; + gap: 10px; +} + .footer-links-list a { font-size: 0.88rem; - color: rgba(255,255,255,0.6); + color: rgba(255, 255, 255, 0.6); transition: color var(--t); } -.footer-links-list a:hover { color: var(--white); text-decoration: none; } + +.footer-links-list a:hover { + color: var(--white); + text-decoration: none; +} .footer-bottom { max-width: 1140px; @@ -1134,32 +1450,52 @@ select:focus { justify-content: space-between; gap: 16px; } -.footer-bottom p { font-size: 0.82rem; color: rgba(255,255,255,0.35); } -.footer-bottom-links { display: flex; gap: 20px; } -.footer-bottom-links a { font-size: 0.82rem; color: rgba(255,255,255,0.35); transition: color var(--t); } -.footer-bottom-links a:hover { color: rgba(255,255,255,0.7); text-decoration: none; } -/* ---- Detail Page ------------------------------------------ */ -.detail-page { background: var(--gray-50); } +.footer-bottom p { + font-size: 0.82rem; + color: rgba(255, 255, 255, 0.35); +} -.detail-hero { - background: linear-gradient(135deg, var(--indigo-900) 0%, var(--indigo-800) 50%, var(--purple-700) 100%); - padding: 108px 0 60px; - position: relative; +.footer-bottom-links { + display: flex; + gap: 20px; +} + +.footer-bottom-links a { + font-size: 0.82rem; + color: rgba(255, 255, 255, 0.35); + transition: color var(--t); +} + +.footer-bottom-links a:hover { + color: rgba(255, 255, 255, 0.7); + text-decoration: none; +} + +/* ---- Detail Page ------------------------------------------ */ +.detail-page { + background: var(--gray-50); +} + +.detail-hero { + background: linear-gradient(135deg, var(--indigo-900) 0%, var(--indigo-800) 50%, var(--purple-700) 100%); + padding: 108px 0 60px; + position: relative; overflow: hidden; } + .detail-hero::after { content: ""; position: absolute; inset: 0; - background-image: radial-gradient(rgba(255,255,255,0.04) 1px, transparent 1px); + background-image: radial-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px); background-size: 28px 28px; pointer-events: none; } .breadcrumb { font-size: 0.82rem; - color: rgba(255,255,255,0.5); + color: rgba(255, 255, 255, 0.5); display: flex; align-items: center; gap: 6px; @@ -1167,9 +1503,19 @@ select:focus { position: relative; z-index: 2; } -.breadcrumb a { color: rgba(255,255,255,0.5); } -.breadcrumb a:hover { color: var(--white); } -.breadcrumb-sep { opacity: 0.4; font-size: 1rem; } + +.breadcrumb a { + color: rgba(255, 255, 255, 0.5); +} + +.breadcrumb a:hover { + color: var(--white); +} + +.breadcrumb-sep { + opacity: 0.4; + font-size: 1rem; +} .detail-hero-content { display: flex; @@ -1179,9 +1525,19 @@ select:focus { position: relative; z-index: 2; } -.detail-hero-left { flex: 1; max-width: 680px; } -.detail-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; } +.detail-hero-left { + flex: 1; + max-width: 680px; +} + +.detail-tags { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 18px; +} + .detail-tag { font-size: 0.74rem; font-weight: 700; @@ -1190,9 +1546,21 @@ select:focus { padding: 4px 13px; 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); @@ -1203,9 +1571,10 @@ select:focus { line-height: 1.15; margin-bottom: 16px; } + .detail-description { font-size: 1.02rem; - color: rgba(255,255,255,0.72); + color: rgba(255, 255, 255, 0.72); line-height: 1.78; max-width: 600px; } @@ -1217,6 +1586,7 @@ select:focus { flex-shrink: 0; padding-top: 52px; } + .btn-download { display: inline-flex; align-items: center; @@ -1229,18 +1599,23 @@ select:focus { font-weight: 700; border-radius: var(--r-xs); white-space: nowrap; - box-shadow: 0 4px 16px rgba(251,191,36,0.35); + box-shadow: 0 4px 16px rgba(251, 191, 36, 0.35); transition: background var(--t), transform var(--t); } -.btn-download:hover { background: var(--yellow-300); transform: translateY(-1px); text-decoration: none; } + +.btn-download:hover { + background: var(--yellow-300); + transform: translateY(-1px); + text-decoration: none; +} .btn-view-code { display: inline-flex; align-items: center; gap: 8px; padding: 13px 22px; - background: rgba(255,255,255,0.08); - border: 1.5px solid rgba(255,255,255,0.28); + background: rgba(255, 255, 255, 0.08); + border: 1.5px solid rgba(255, 255, 255, 0.28); color: var(--white); font-family: var(--font-display); font-size: 0.9rem; @@ -1250,10 +1625,16 @@ select:focus { white-space: nowrap; transition: background var(--t); } -.btn-view-code:hover { background: rgba(255,255,255,0.16); } + +.btn-view-code:hover { + background: rgba(255, 255, 255, 0.16); +} /* Detail body */ -.detail-body { padding: 56px 0 96px; } +.detail-body { + padding: 56px 0 96px; +} + .detail-grid { display: grid; grid-template-columns: 1fr 310px; @@ -1269,26 +1650,33 @@ select:focus { box-shadow: var(--shadow-sm); margin-bottom: 24px; } + .detail-section-header { display: flex; align-items: center; gap: 12px; margin-bottom: 24px; } + .detail-section-icon { - width: 36px; height: 36px; + width: 36px; + height: 36px; background: var(--indigo-100); border-radius: var(--r-xs); - display: flex; align-items: center; justify-content: center; + display: flex; + align-items: center; + justify-content: center; color: var(--indigo-600); flex-shrink: 0; } + .detail-section-header h2 { font-family: var(--font-display); font-size: 1.1rem; font-weight: 700; color: var(--text-heading); } + .detail-section-sub { font-size: 0.87rem; color: var(--text-body); @@ -1297,7 +1685,12 @@ select:focus { } /* Features list */ -.feature-list { display: flex; flex-direction: column; gap: 12px; } +.feature-list { + display: flex; + flex-direction: column; + gap: 12px; +} + .feature-list-item { display: flex; align-items: flex-start; @@ -1306,19 +1699,31 @@ select:focus { color: var(--text-body); line-height: 1.65; } + .feature-check { - width: 22px; height: 22px; + width: 22px; + height: 22px; background: var(--green-100); border-radius: 50%; - display: flex; align-items: center; justify-content: center; + display: flex; + align-items: center; + justify-content: center; color: var(--green-500); flex-shrink: 0; margin-top: 2px; } /* Roadmap timeline */ -.roadmap-timeline { display: flex; flex-direction: column; } -.roadmap-step { display: flex; gap: 0; } +.roadmap-timeline { + display: flex; + flex-direction: column; +} + +.roadmap-step { + display: flex; + gap: 0; +} + .roadmap-marker { display: flex; flex-direction: column; @@ -1326,22 +1731,34 @@ select:focus { flex-shrink: 0; width: 36px; } + .roadmap-dot { - width: 14px; height: 14px; + width: 14px; + height: 14px; border-radius: 50%; background: var(--indigo-600); border: 3px solid var(--indigo-100); - position: relative; z-index: 1; + position: relative; + z-index: 1; margin-top: 4px; } + .roadmap-line { flex: 1; width: 2px; background: var(--border); margin: 4px 0; } -.roadmap-step:last-child .roadmap-line { display: none; } -.roadmap-content { padding: 0 0 28px 16px; flex: 1; } + +.roadmap-step:last-child .roadmap-line { + display: none; +} + +.roadmap-content { + padding: 0 0 28px 16px; + flex: 1; +} + .roadmap-step-num { display: inline-block; font-size: 0.72rem; @@ -1353,11 +1770,24 @@ select:focus { letter-spacing: 0.04em; margin-bottom: 6px; } -.roadmap-step-text { font-size: 0.92rem; color: var(--text-body); line-height: 1.65; } + +.roadmap-step-text { + font-size: 0.92rem; + color: var(--text-body); + line-height: 1.65; +} /* Resources list */ -.resource-list { display: flex; flex-direction: column; gap: 10px; } -.resource-item { display: flex; } +.resource-list { + display: flex; + flex-direction: column; + gap: 10px; +} + +.resource-item { + display: flex; +} + .resource-link { display: inline-flex; align-items: center; @@ -1372,12 +1802,32 @@ select:focus { width: 100%; transition: background var(--t), border-color var(--t); } -.resource-link:hover { background: var(--indigo-100); border-color: rgba(79, 110, 247, 0.3); text-decoration: none; } -.resource-link span { flex: 1; } -.resource-plain { font-size: 0.9rem; color: var(--text-body); padding: 8px 0; } + +.resource-link:hover { + background: var(--indigo-100); + border-color: rgba(79, 110, 247, 0.3); + text-decoration: none; +} + +.resource-link span { + flex: 1; +} + +.resource-plain { + font-size: 0.9rem; + color: var(--text-body); + padding: 8px 0; +} /* Sidebar */ -.detail-sidebar { display: flex; flex-direction: column; gap: 20px; position: sticky; top: 84px; } +.detail-sidebar { + display: flex; + flex-direction: column; + gap: 20px; + position: sticky; + top: 84px; +} + .sidebar-card { background: var(--white); border: 1px solid var(--border); @@ -1385,12 +1835,16 @@ select:focus { padding: 24px; box-shadow: var(--shadow-sm); } + .sidebar-card--code { background: linear-gradient(135deg, var(--indigo-50) 0%, var(--purple-100) 100%); border-color: rgba(79, 110, 247, 0.18); } + .sidebar-card-title { - display: flex; align-items: center; gap: 8px; + display: flex; + align-items: center; + gap: 8px; font-family: var(--font-display); font-size: 0.82rem; font-weight: 700; @@ -1399,7 +1853,13 @@ select:focus { text-transform: uppercase; letter-spacing: 0.07em; } -.tech-tags { display: flex; flex-wrap: wrap; gap: 8px; } + +.tech-tags { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + .tech-tag { font-size: 0.8rem; font-weight: 500; @@ -1409,15 +1869,54 @@ select:focus { padding: 4px 12px; border-radius: var(--r-full); } -.stats-list { display: flex; flex-direction: column; gap: 12px; } -.stats-list li { display: flex; align-items: center; justify-content: space-between; font-size: 0.88rem; } -.stats-label { color: var(--text-body); } -.stats-value { font-weight: 600; color: var(--text-heading); font-size: 0.85rem; } -.stats-value--beginner { color: #065f46; } -.stats-value--intermediate { color: #78350f; } -.stats-value--advanced { color: #7f1d1d; } -.sidebar-card-desc { font-size: 0.85rem; color: var(--text-body); line-height: 1.65; margin-bottom: 16px; } -.sidebar-code-actions { display: flex; gap: 10px; } + +.stats-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.stats-list li { + display: flex; + align-items: center; + justify-content: space-between; + font-size: 0.88rem; +} + +.stats-label { + color: var(--text-body); +} + +.stats-value { + font-weight: 600; + color: var(--text-heading); + font-size: 0.85rem; +} + +.stats-value--beginner { + color: #065f46; +} + +.stats-value--intermediate { + color: #78350f; +} + +.stats-value--advanced { + color: #7f1d1d; +} + +.sidebar-card-desc { + font-size: 0.85rem; + color: var(--text-body); + line-height: 1.65; + margin-bottom: 16px; +} + +.sidebar-code-actions { + display: flex; + gap: 10px; +} + .btn-view-code-sm { flex: 1; padding: 9px 14px; @@ -1432,7 +1931,12 @@ select:focus { text-align: center; transition: background var(--t), color var(--t); } -.btn-view-code-sm:hover { background: var(--indigo-600); color: var(--white); } + +.btn-view-code-sm:hover { + background: var(--indigo-600); + color: var(--white); +} + .btn-download-sm { flex: 1; padding: 9px 14px; @@ -1446,65 +1950,99 @@ select:focus { display: block; transition: background var(--t); } -.btn-download-sm:hover { background: var(--yellow-300); text-decoration: none; } + +.btn-download-sm:hover { + background: var(--yellow-300); + text-decoration: none; +} /* ---- Code Panel (slide-up) -------------------------------- */ .code-panel-overlay { display: none; - position: fixed; inset: 0; + position: fixed; + inset: 0; background: rgba(10, 15, 80, 0.6); z-index: 300; } -.code-panel-overlay.active { display: block; } + +.code-panel-overlay.active { + display: block; +} + .code-panel { position: fixed; - bottom: 0; left: 0; right: 0; + bottom: 0; + left: 0; + right: 0; height: 72vh; background: #0d1117; border-radius: var(--r-lg) var(--r-lg) 0 0; - box-shadow: 0 -8px 48px rgba(0,0,0,0.45); + box-shadow: 0 -8px 48px rgba(0, 0, 0, 0.45); z-index: 301; display: flex; flex-direction: column; transform: translateY(100%); transition: transform 0.3s ease; } -.code-panel.active { transform: translateY(0); } + +.code-panel.active { + transform: translateY(0); +} + .code-panel-header { - display: flex; align-items: center; justify-content: space-between; + display: flex; + align-items: center; + justify-content: space-between; padding: 14px 22px; - border-bottom: 1px solid rgba(255,255,255,0.06); + border-bottom: 1px solid rgba(255, 255, 255, 0.06); flex-shrink: 0; } + .code-panel-title { - display: flex; align-items: center; gap: 8px; + display: flex; + align-items: center; + gap: 8px; font-family: var(--font-mono); font-size: 0.84rem; - color: rgba(255,255,255,0.6); + color: rgba(255, 255, 255, 0.6); } -.code-panel-actions { display: flex; align-items: center; gap: 10px; } + +.code-panel-actions { + display: flex; + align-items: center; + gap: 10px; +} + .code-panel-download { font-size: 0.82rem; font-weight: 600; color: var(--yellow-400); padding: 5px 14px; - border: 1px solid rgba(251,191,36,0.3); + border: 1px solid rgba(251, 191, 36, 0.3); border-radius: var(--r-full); transition: background var(--t); } -.code-panel-download:hover { background: rgba(251,191,36,0.1); text-decoration: none; } + +.code-panel-download:hover { + background: rgba(251, 191, 36, 0.1); + text-decoration: none; +} + .code-panel-close { - background: rgba(255,255,255,0.07); + background: rgba(255, 255, 255, 0.07); border: none; border-radius: var(--r-xs); padding: 6px 16px; font-size: 0.84rem; font-weight: 600; - color: rgba(255,255,255,0.6); + color: rgba(255, 255, 255, 0.6); cursor: pointer; transition: background var(--t); } -.code-panel-close:hover { background: rgba(255,255,255,0.13); } + +.code-panel-close:hover { + background: rgba(255, 255, 255, 0.13); +} /* Copy Code button */ .btn-copy-code { @@ -1521,12 +2059,17 @@ select:focus { cursor: pointer; transition: background var(--t), border-color var(--t), color var(--t), transform 0.1s ease; } + .btn-copy-code:hover { background: rgba(79, 110, 247, 0.28); border-color: var(--indigo-500); color: #a5b4fc; } -.btn-copy-code:active { transform: scale(0.97); } + +.btn-copy-code:active { + transform: scale(0.97); +} + .btn-copy-code.copied { background: rgba(16, 185, 129, 0.18); border-color: rgba(16, 185, 129, 0.4); @@ -1554,13 +2097,15 @@ select:focus { pointer-events: none; transition: opacity 0.25s ease, transform 0.25s ease; } + .copy-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); } .code-viewer { - flex: 1; overflow: auto; + flex: 1; + overflow: auto; padding: 24px 28px; font-family: var(--font-mono); font-size: 0.83rem; @@ -1573,11 +2118,17 @@ select:focus { /* ---- Error Pages ------------------------------------------ */ .error-page { min-height: 100vh; - display: flex; align-items: center; justify-content: center; + display: flex; + align-items: center; + justify-content: center; text-align: center; padding: 40px 24px; } -.error-page-inner { max-width: 440px; } + +.error-page-inner { + max-width: 440px; +} + .error-code { font-family: var(--font-display); font-size: 7rem; @@ -1586,6 +2137,7 @@ select:focus { line-height: 1; margin-bottom: 16px; } + .error-page-inner h1 { font-family: var(--font-display); font-size: 1.5rem; @@ -1593,7 +2145,11 @@ select:focus { color: var(--text-heading); margin-bottom: 12px; } -.error-page-inner p { color: var(--text-body); margin-bottom: 32px; } + +.error-page-inner p { + color: var(--text-body); + margin-bottom: 32px; +} /* Primary button (used in error pages) */ .btn-primary { @@ -1610,50 +2166,127 @@ select:focus { box-shadow: 0 4px 18px rgba(35, 53, 194, 0.3); transition: opacity var(--t), transform var(--t); } -.btn-primary:hover { opacity: 0.92; transform: translateY(-1px); text-decoration: none; } + +.btn-primary:hover { + opacity: 0.92; + transform: translateY(-1px); + text-decoration: none; +} /* ---- Responsive ------------------------------------------- */ @media (max-width: 1024px) { - .hero-inner { grid-template-columns: 1fr; gap: 48px; } - .hero-visual { max-width: 480px; margin: 0 auto; } - .detail-grid { grid-template-columns: 1fr; } - .detail-sidebar { position: static; } - .detail-hero-content { flex-direction: column; gap: 28px; } - .detail-hero-actions { flex-direction: row; padding-top: 0; } - .footer-inner { grid-template-columns: 1fr 1fr; row-gap: 40px; } + .hero-inner { + grid-template-columns: 1fr; + gap: 48px; + } + + .hero-visual { + max-width: 480px; + margin: 0 auto; + } + + .detail-grid { + grid-template-columns: 1fr; + } + + .detail-sidebar { + position: static; + } + + .detail-hero-content { + flex-direction: column; + gap: 28px; + } + + .detail-hero-actions { + flex-direction: row; + padding-top: 0; + } + + .footer-inner { + grid-template-columns: 1fr 1fr; + row-gap: 40px; + } } @media (max-width: 860px) { - .features-grid { grid-template-columns: 1fr; } - .steps-grid { flex-direction: column; align-items: stretch; } - .step-connector { display: none; } - .step-card { max-width: 100%; } + .features-grid { + grid-template-columns: 1fr; + } + + .steps-grid { + flex-direction: column; + align-items: stretch; + } + + .step-connector { + display: none; + } + + .step-card { + max-width: 100%; + } } @media (max-width: 640px) { - .nav-links { display: none; } - .nav-mobile-toggle { display: flex; } - .nav-inner { padding: 0 20px; } + .nav-links { + display: none; + } + + .nav-mobile-toggle { + display: flex; + } + + .nav-inner { + padding: 0 20px; + } + + .hero { + padding: 110px 20px 72px; + } + + .hero-stats { + gap: 16px; + } - .hero { padding: 110px 20px 72px; } - .hero-stats { gap: 16px; } + .form-card { + padding: 28px 22px 24px; + } - .form-card { padding: 28px 22px 24px; } .form-row { grid-template-columns: 1fr; gap: 16px; - } + } - .results-grid { grid-template-columns: 1fr; } + .results-grid { + grid-template-columns: 1fr; + } + + .detail-hero-actions { + flex-direction: column; + } + + .code-panel { + height: 82vh; + } + + .footer-inner { + grid-template-columns: 1fr; + } - .detail-hero-actions { flex-direction: column; } - .code-panel { height: 82vh; } + .footer-bottom { + flex-direction: column; + align-items: flex-start; + gap: 10px; + } - .footer-inner { grid-template-columns: 1fr; } - .footer-bottom { flex-direction: column; align-items: flex-start; gap: 10px; } + .container { + padding: 0 20px; + } - .container { padding: 0 20px; } - .section-sub { margin-bottom: 40px; } + .section-sub { + margin-bottom: 40px; + } } @@ -1680,3 +2313,177 @@ select:focus { color: #94a3b8; line-height: 1.5; } + +.theme-btn { + background: transparent; + cursor: pointer; +} + +.theme-btn:hover { + text-decoration: none; +} + + +/* ========================================= + DARK MODE +========================================= */ + +.dark-mode { + + background: #020617; + + color: #f8fafc; +} + +/* Navbar */ + +.dark-mode .navbar { + + background: + rgba(2, 6, 23, 0.9); + + border-bottom: + 1px solid rgba(255, 255, 255, 0.08); +} + +/* Hero Section */ + +.dark-mode .hero { + + background: + linear-gradient(135deg, + #020617 0%, + #111827 45%, + #312e81 100%); +} + +/* Cards */ + +.dark-mode .feature-card, +.dark-mode .project-card, +.dark-mode .roadmap-card { + + background: #111827; + + border: + 1px solid rgba(255, 255, 255, 0.08); + + color: #f8fafc; +} + +/* Text */ + +.dark-mode p, +.dark-mode .hero-description, +.dark-mode .section-subtitle { + + color: #cbd5e1; +} + +/* Buttons */ + +.dark-mode .nav-btn-outline { + + border: + 1px solid rgba(255, 255, 255, 0.18); + + color: white; +} + +/* Sections */ + +.dark-mode section { + + background: #020617; +} + +/* Inputs */ + +.dark-mode input, +.dark-mode select { + + background: #111827; + + color: white; + + border: + 1px solid rgba(255, 255, 255, 0.08); +} + +/* ================================= + EXTRA DARK MODE FIXES +================================= */ + +/* Skills strip */ + +.dark-mode .skills-strip { + + background: #0f172a; + + border-top: + 1px solid rgba(255, 255, 255, 0.08); + + border-bottom: + 1px solid rgba(255, 255, 255, 0.08); +} + +.dark-mode .skills-strip span { + + color: #e2e8f0; +} + +/* Step Cards */ + +.dark-mode .step-card { + + background: #111827; + + border: + 1px solid rgba(255, 255, 255, 0.06); +} + +/* Recommendation Form */ + +.dark-mode .recommendation-form { + + background: #111827; + + border: + 1px solid rgba(255, 255, 255, 0.08); +} + +/* Inputs */ + +.dark-mode input, +.dark-mode select { + + background: #0f172a; + + color: white; +} + +/* Footer */ + +.dark-mode footer { + + background: #111827; +} + +/* Buttons */ + +.dark-mode .btn-secondary { + + background: #1e293b; + + color: white; +} + +/* Text headings */ + +.dark-mode h1, +.dark-mode h2, +.dark-mode h3, +.dark-mode h4 { + + color: white; +} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index c70abf72..65ae5527 100644 --- a/templates/index.html +++ b/templates/index.html @@ -11,6 +11,8 @@ + + @@ -18,6 +20,9 @@ Navigation ============================================================ -->