Skip to content

Commit 5cf1c82

Browse files
authored
Fix/light mode UI (JhaSourav07#1212)
## Description This PR resolves the faded layout issues in Light Mode, bringing it up to the "premium quality" aesthetic of the Dark Mode. It improves the contrast, visibility, and depth of key elements on the landing page, ensuring the design is accessible and engaging across both themes. **Specific changes:** - Updated `navbar.tsx` to include a frosted white glass effect and adjusted text/icon colors for light mode readability. - Improved `HeroSection.tsx` input fields and buttons with defined borders, a primary CTA highlight color (`#5C45FD`), and responsive hover states. - Adjusted `BrandParticles.tsx` base opacity and implemented responsive dark mode classes so the floating particles pop vibrantly on white backgrounds while remaining subtle in dark mode. Fixes JhaSourav07#1204 ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [X] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview BEFORE <img width="1915" height="947" alt="Screenshot 2026-05-29 111153" src="https://github.com/user-attachments/assets/e4ce664e-eb56-46d4-8226-6cfcfae28de3" /> AFFTER <img width="1918" height="837" alt="Screenshot 2026-05-29 132641" src="https://github.com/user-attachments/assets/cb4b6dab-31a3-4314-9a11-8c99f912df6a" /> ## Checklist before requesting a review: - [X] I have read the `CONTRIBUTING.md` file. - [X] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [X] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [X] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [X] I have updated `README.md` if I added a new theme or URL parameter. - [X] I have started the repo. - [X] I have made sure that i have only one commit to merge in this PR. - [X] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [X] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 9b0b764 + fe809c7 commit 5cf1c82

3 files changed

Lines changed: 51 additions & 29 deletions

File tree

app/components/HeroSection.tsx

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
'use client';
22

33
import { motion } from 'framer-motion';
4+
import { Copy } from 'lucide-react';
45

56
export function HeroSection() {
67
return (
7-
<div className="relative text-center mb-16 overflow-hidden bg-[radial-gradient(circle_at_center,rgba(34,197,94,0.08),transparent_70%)]">
8-
<div className="absolute inset-0 opacity-10 bg-[linear-gradient(rgba(255,255,255,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.06)_1px,transparent_1px)] bg-[size:40px_40px]" />
8+
<div className="relative text-center mb-16 overflow-hidden bg-[radial-gradient(circle_at_center,rgba(34,197,94,0.04),transparent_70%)] dark:bg-[radial-gradient(circle_at_center,rgba(34,197,94,0.08),transparent_70%)] transition-colors duration-300">
9+
<div className="absolute inset-0 opacity-20 dark:opacity-10 bg-[linear-gradient(rgba(0,0,0,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(0,0,0,0.06)_1px,transparent_1px)] dark:bg-[linear-gradient(rgba(255,255,255,0.06)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.06)_1px,transparent_1px)] bg-[size:40px_40px]" />
910

10-
<div className="absolute inset-0 blur-3xl opacity-20 bg-gradient-to-r from-green-500 via-cyan-500 to-purple-500 rounded-full" />
11+
<div className="absolute inset-0 blur-3xl opacity-10 dark:opacity-20 bg-gradient-to-r from-green-500 via-cyan-500 to-purple-500 rounded-full" />
1112

12-
<div className="absolute top-16 left-10 grid grid-cols-6 gap-2 opacity-30">
13+
<div className="absolute top-16 left-10 grid grid-cols-6 gap-2 opacity-50 dark:opacity-30">
1314
{Array.from({ length: 24 }).map((_, i) => (
1415
<div
1516
key={i}
16-
className="w-2 h-2 rounded-sm bg-green-400 animate-pulse"
17+
className="w-2 h-2 rounded-sm bg-green-500 dark:bg-green-400 animate-pulse"
1718
style={{
1819
animationDelay: `${i * 0.1}s`,
1920
}}
@@ -27,7 +28,7 @@ export function HeroSection() {
2728
transition={{ duration: 0.6 }}
2829
className="relative"
2930
>
30-
<h1 className="text-5xl md:text-8xl font-extrabold tracking-tight mb-8 bg-gradient-to-r from-green-400 via-cyan-400 to-purple-500 bg-clip-text text-transparent">
31+
<h1 className="text-5xl md:text-8xl font-extrabold tracking-tight mb-8 bg-gradient-to-r from-green-500 via-cyan-500 to-purple-600 dark:from-green-400 dark:via-cyan-400 dark:to-purple-500 bg-clip-text text-transparent">
3132
Elevate Your <br /> Contribution Story.
3233
</h1>
3334
</motion.div>
@@ -36,7 +37,7 @@ export function HeroSection() {
3637
initial={{ opacity: 0 }}
3738
animate={{ opacity: 1 }}
3839
transition={{ delay: 0.3 }}
39-
className="relative text-gray-300 text-lg md:text-xl max-w-2xl mx-auto leading-relaxed"
40+
className="relative text-gray-600 dark:text-gray-300 text-lg md:text-xl max-w-2xl mx-auto leading-relaxed"
4041
>
4142
Stop settling for flat grids. Generate high-fidelity, 3D isometric monoliths that visualize
4243
your coding rhythm with professional precision.
@@ -48,18 +49,39 @@ export function HeroSection() {
4849
transition={{ delay: 0.5 }}
4950
className="relative mt-10 flex flex-wrap items-center justify-center gap-4"
5051
>
51-
<div className="px-4 py-2 rounded-full border border-green-500/20 bg-green-500/10 text-green-400 text-sm font-medium">
52+
<div className="px-4 py-2 rounded-full border border-green-500/20 bg-green-500/10 text-green-700 dark:text-green-400 text-sm font-medium">
5253
● 1,247 Contributions
5354
</div>
5455

55-
<div className="px-4 py-2 rounded-full border border-cyan-500/20 bg-cyan-500/10 text-cyan-400 text-sm font-medium">
56+
<div className="px-4 py-2 rounded-full border border-cyan-500/20 bg-cyan-500/10 text-cyan-700 dark:text-cyan-400 text-sm font-medium">
5657
● 83 Pull Requests
5758
</div>
5859

59-
<div className="px-4 py-2 rounded-full border border-purple-500/20 bg-purple-500/10 text-purple-400 text-sm font-medium">
60+
<div className="px-4 py-2 rounded-full border border-purple-500/20 bg-purple-500/10 text-purple-700 dark:text-purple-400 text-sm font-medium">
6061
● 214 Commits
6162
</div>
6263
</motion.div>
64+
65+
{/* Fully Configured Light/Dark Mode Input Form */}
66+
<motion.div
67+
initial={{ opacity: 0, y: 20 }}
68+
animate={{ opacity: 1, y: 0 }}
69+
transition={{ delay: 0.7 }}
70+
className="relative mt-12 max-w-3xl mx-auto flex flex-col sm:flex-row items-center gap-3 p-2 rounded-2xl border border-gray-200 bg-white/70 shadow-sm backdrop-blur-md dark:border-white/10 dark:bg-white/5 dark:shadow-none"
71+
>
72+
<input
73+
type="text"
74+
placeholder="Enter GitHub Username"
75+
className="flex-1 w-full bg-transparent border-none px-4 py-3 text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-0 dark:text-white dark:placeholder-gray-500"
76+
/>
77+
<button className="flex items-center gap-2 px-6 py-3 rounded-xl border border-gray-200 bg-gray-50 text-gray-700 font-medium transition hover:bg-gray-100 dark:border-white/20 dark:bg-white/10 dark:text-white dark:hover:bg-white/20">
78+
<Copy size={18} />
79+
Copy Link
80+
</button>
81+
<button className="px-6 py-3 rounded-xl bg-[#5C45FD] text-white font-medium shadow-lg shadow-[#5C45FD]/30 transition hover:bg-[#4a35da] hover:shadow-[#5C45FD]/50">
82+
Watch Dashboard
83+
</button>
84+
</motion.div>
6385
</div>
6486
);
6587
}

app/components/navbar.tsx

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export default function Navbar() {
3232

3333
const [isDark, setIsDark] = useState(() => {
3434
if (typeof window === 'undefined') return true;
35-
3635
return localStorage.getItem('theme') !== 'light';
3736
});
3837

@@ -62,8 +61,6 @@ export default function Navbar() {
6261
}
6362
};
6463

65-
// Defer the initial check so it doesn't cause a synchronous setState
66-
// inside the effect body (which would trigger cascading re-renders).
6764
const initialCheckTimer = setTimeout(() => {
6865
if (mediaQuery.matches) {
6966
setOpen(false);
@@ -88,23 +85,23 @@ export default function Navbar() {
8885
<div className="mx-auto max-w-6xl">
8986
<div
9087
ref={shellRef}
91-
className="relative overflow-hidden rounded-2xl border border-white/25 bg-black/45 backdrop-blur-xl shadow-[0_14px_40px_rgba(0,0,0,0.45)]"
88+
className="relative overflow-hidden rounded-2xl border border-gray-200 bg-white/70 dark:border-white/25 dark:bg-black/45 backdrop-blur-xl shadow-[0_8px_30px_rgba(0,0,0,0.08)] dark:shadow-[0_14px_40px_rgba(0,0,0,0.45)] transition-colors duration-300"
9289
style={shellVars}
9390
onMouseEnter={handleMouseEnter}
9491
onMouseMove={handleMouseMove}
9592
onMouseLeave={handleMouseLeave}
9693
>
9794
<div
98-
className="pointer-events-none absolute inset-0 transition-opacity duration-300 ease-out"
95+
className="pointer-events-none absolute inset-0 transition-opacity duration-300 ease-out hidden dark:block"
9996
style={{
10097
opacity: 'var(--glow-opacity)',
10198
background:
10299
'radial-gradient(180px 105px at var(--mx) var(--my), rgba(255,255,255,0.26), rgba(191,219,254,0.18) 30%, rgba(244,114,182,0.1) 48%, rgba(0,0,0,0) 68%)',
103100
}}
104101
/>
105-
<div className="pointer-events-none absolute inset-0 rounded-2xl border border-white/20" />
102+
<div className="pointer-events-none absolute inset-0 rounded-2xl border border-black/5 dark:border-white/20" />
106103
<div
107-
className="pointer-events-none absolute inset-0 rounded-2xl p-px transition-opacity duration-300 ease-out"
104+
className="pointer-events-none absolute inset-0 rounded-2xl p-px transition-opacity duration-300 ease-out hidden dark:block"
108105
style={{
109106
opacity: 'var(--border-opacity)',
110107
background:
@@ -121,10 +118,10 @@ export default function Navbar() {
121118
className="group inline-flex items-center gap-3"
122119
onClick={handleLogoClick}
123120
>
124-
<span className="flex h-10 w-10 items-center justify-center rounded-xl border border-white/35 bg-white/10 text-white shadow-[0_0_25px_rgba(255,255,255,0.22)] transition-transform duration-300 group-hover:scale-105">
121+
<span className="flex h-10 w-10 items-center justify-center rounded-xl border border-gray-200 bg-gray-50 text-gray-800 shadow-sm dark:border-white/35 dark:bg-white/10 dark:text-white dark:shadow-[0_0_25px_rgba(255,255,255,0.22)] transition-transform duration-300 group-hover:scale-105">
125122
<Activity size={19} />
126123
</span>
127-
<span className="text-base font-semibold tracking-[0.08em] text-white sm:text-lg">
124+
<span className="text-base font-semibold tracking-[0.08em] text-gray-900 dark:text-white sm:text-lg">
128125
CommitPulse
129126
</span>
130127
</Link>
@@ -133,7 +130,7 @@ export default function Navbar() {
133130
<button
134131
type="button"
135132
onClick={toggleTheme}
136-
className="inline-flex h-10 w-10 items-center justify-center rounded-xl border border-white/15 bg-white/5 text-white transition hover:bg-white/10"
133+
className="inline-flex h-10 w-10 items-center justify-center rounded-xl border border-gray-200 bg-gray-50 text-gray-700 transition hover:bg-gray-100 dark:border-white/15 dark:bg-white/5 dark:text-white dark:hover:bg-white/10"
137134
aria-label="Toggle theme"
138135
>
139136
{mounted ? (
@@ -153,7 +150,7 @@ export default function Navbar() {
153150
href={link.href}
154151
target={link.isExternal ? '_blank' : undefined}
155152
rel={link.isExternal ? 'noopener noreferrer' : undefined}
156-
className="inline-flex items-center gap-2 rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm font-medium text-white/90 transition hover:border-white/45 hover:bg-white/10"
153+
className="inline-flex items-center gap-2 rounded-xl border border-gray-200 bg-gray-50 px-4 py-2 text-sm font-medium text-gray-700 transition hover:border-gray-300 hover:bg-gray-100 dark:border-white/15 dark:bg-white/5 dark:text-white/90 dark:hover:border-white/45 dark:hover:bg-white/10"
157154
>
158155
{link.isExternal && <GithubMark />}
159156
{link.label}
@@ -165,14 +162,14 @@ export default function Navbar() {
165162
<button
166163
type="button"
167164
onClick={toggleTheme}
168-
className="hidden sm:inline-flex h-10 w-10 items-center justify-center rounded-xl border border-white/15 bg-white/5 text-white transition hover:bg-white/10"
165+
className="hidden sm:inline-flex h-10 w-10 items-center justify-center rounded-xl border border-gray-200 bg-gray-50 text-gray-700 transition hover:bg-gray-100 dark:border-white/15 dark:bg-white/5 dark:text-white dark:hover:bg-white/10"
169166
aria-label="Toggle theme"
170167
>
171168
{isDark ? <Sun size={18} /> : <Moon size={18} />}
172169
</button>
173170
<button
174171
type="button"
175-
className="md:hidden inline-flex items-center justify-center rounded-xl border border-white/15 bg-white/5 p-2 text-white/90 transition hover:bg-white/10"
172+
className="md:hidden inline-flex items-center justify-center rounded-xl border border-gray-200 bg-gray-50 p-2 text-gray-700 transition hover:bg-gray-100 dark:border-white/15 dark:bg-white/5 dark:text-white/90 dark:hover:bg-white/10"
176173
aria-label={open ? 'Close menu' : 'Open menu'}
177174
aria-expanded={open}
178175
onClick={() => setOpen((prev) => !prev)}
@@ -183,7 +180,7 @@ export default function Navbar() {
183180
</nav>
184181

185182
{open ? (
186-
<div className="border-t border-white/10 px-4 py-3 md:hidden">
183+
<div className="border-t border-gray-200 dark:border-white/10 px-4 py-3 md:hidden">
187184
<ul className="space-y-2">
188185
{NAV_LINKS.map((link) => (
189186
<li key={link.href}>
@@ -192,18 +189,19 @@ export default function Navbar() {
192189
target={link.isExternal ? '_blank' : undefined}
193190
rel={link.isExternal ? 'noopener noreferrer' : undefined}
194191
onClick={() => setOpen(false)}
195-
className="inline-flex w-full items-center gap-2 rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm font-medium text-white/90 transition hover:border-white/45 hover:bg-white/10"
192+
className="inline-flex w-full items-center gap-2 rounded-xl border border-gray-200 bg-gray-50 px-4 py-2 text-sm font-medium text-gray-700 transition hover:border-gray-300 hover:bg-gray-100 dark:border-white/15 dark:bg-white/5 dark:text-white/90 dark:hover:border-white/45 dark:hover:bg-white/10"
196193
>
197194
{link.isExternal && <GithubMark />}
198195
{link.label}
199196
</a>
200197
</li>
201198
))}
202-
<li className="sm:hidden">
199+
200+
<li className="sm:hidden pt-2 mt-2 border-t border-gray-200 dark:border-white/10">
203201
<button
204202
type="button"
205203
onClick={toggleTheme}
206-
className="inline-flex w-full items-center gap-2 rounded-xl border border-white/15 bg-white/5 px-4 py-2 text-sm font-medium text-white/90 transition hover:border-white/45 hover:bg-white/10"
204+
className="inline-flex w-full items-center gap-2 rounded-xl border border-gray-200 bg-gray-50 px-4 py-2 text-sm font-medium text-gray-700 transition hover:border-gray-300 hover:bg-gray-100 dark:border-white/15 dark:bg-white/5 dark:text-white/90 dark:hover:border-white/45 dark:hover:bg-white/10"
207205
aria-label="Toggle theme"
208206
>
209207
{isDark ? <Sun size={18} /> : <Moon size={18} />}

components/BrandParticles.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ const generateParticles = (count: number) => {
1515
duration: Math.random() * 30 + 30, // 30s to 60s duration
1616
delay: Math.random() * -60, // Negative delay so they start already moving
1717
rotateDirection: Math.random() > 0.5 ? 1 : -1,
18-
opacity: 0.1 + Math.random() * 0.15, // subtle opacity (0.1 to 0.25)
18+
// Increased base opacity for light mode visibility
19+
opacity: 0.3 + Math.random() * 0.3,
1920
borderRadius: Math.random() > 0.5 ? '2px' : '50%', // Mix of squares and circles
2021
xAnimStart: Math.random() * 100 - 50,
2122
xAnimEnd: Math.random() * -100 + 50,
@@ -49,7 +50,8 @@ export default function BrandParticles() {
4950
if (!mounted) return null;
5051

5152
return (
52-
<div className="fixed inset-0 pointer-events-none z-[-1] overflow-hidden">
53+
// The parent div dynamically dims the particles in dark mode using `dark:opacity-40`
54+
<div className="fixed inset-0 pointer-events-none z-[-1] overflow-hidden opacity-100 dark:opacity-40 transition-opacity duration-300">
5355
{particles.map((particle) => (
5456
<motion.div
5557
key={particle.id}

0 commit comments

Comments
 (0)