Skip to content

Commit 5d5ba3d

Browse files
committed
UI Improvements & Dark theme
1 parent cf9f43e commit 5d5ba3d

File tree

7 files changed

+816
-732
lines changed

7 files changed

+816
-732
lines changed

astro.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default defineConfig({
66
site: 'https://pwnfuzz.github.io',
77
markdown: {
88
shikiConfig: {
9-
theme: 'github-light', // Use GitHub's light theme for syntax highlighting
9+
theme: 'github-dark',
1010
wrap: true,
1111
},
1212
},

src/components/Header.astro

Lines changed: 123 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,22 @@ const navLinks = [
2727
</li>
2828
))}
2929
</ul>
30-
</nav>
30+
<button id="themeToggle" class="theme-toggle" aria-label="Toggle Dark Mode">
31+
<svg class="sun-icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
32+
<circle cx="12" cy="12" r="5"></circle>
33+
<line x1="12" y1="1" x2="12" y2="3"></line>
34+
<line x1="12" y1="21" x2="12" y2="23"></line>
35+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
36+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
37+
<line x1="1" y1="12" x2="3" y2="12"></line>
38+
<line x1="21" y1="12" x2="23" y2="12"></line>
39+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
40+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
41+
</svg>
42+
<svg class="moon-icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
43+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
44+
</svg>
45+
</button>
3146
</div>
3247
</header>
3348

@@ -37,11 +52,11 @@ const navLinks = [
3752
top: 0;
3853
z-index: 1000;
3954
width: 100%;
40-
background: rgba(255, 255, 255, 0.7); /* Light Glassy */
55+
background: var(--bg-header); /* Use variable for theme support */
4156
backdrop-filter: blur(12px);
4257
-webkit-backdrop-filter: blur(12px);
43-
border-bottom: 1px solid rgba(226, 232, 240, 0.6); /* Subtle border */
44-
transition: transform 0.3s ease;
58+
border-bottom: 1px solid var(--border-subtle); /* Use variable */
59+
transition: transform 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
4560
}
4661

4762
.site-header.hide {
@@ -68,7 +83,7 @@ const navLinks = [
6883
}
6984

7085
.logo-text {
71-
color: var(--fg-primary); /* Clean dark text */
86+
color: var(--fg-primary);
7287
}
7388

7489
.logo-suffix {
@@ -77,9 +92,15 @@ const navLinks = [
7792
font-weight: 500;
7893
}
7994

95+
.main-nav {
96+
display: flex;
97+
align-items: center;
98+
gap: 1rem;
99+
}
100+
80101
.main-nav ul {
81102
display: flex;
82-
gap: 0.5rem; /* Reduced gap for pill spacing */
103+
gap: 0.5rem;
83104
list-style: none;
84105
margin: 0;
85106
padding: 0;
@@ -90,20 +111,26 @@ const navLinks = [
90111
font-size: 0.9rem;
91112
font-weight: 500;
92113
padding: 0.5rem 1rem;
93-
border-radius: 20px; /* Pill shape */
94-
transition: all 0.2s ease;
114+
border-radius: 20px;
115+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
95116
text-decoration: none;
96117
border: none;
118+
position: relative;
119+
}
120+
121+
.main-nav a::after {
122+
display: none; /* Disable the global link underline */
97123
}
98124

99125
.main-nav a:hover {
100126
color: var(--fg-primary);
101-
background: rgba(0, 0, 0, 0.05); /* Subtle hover bg */
127+
background: var(--bg-card-hover);
128+
transform: translateY(-1px);
102129
}
103130

104131
.main-nav a.active {
105-
color: var(--fg-primary);
106-
background: rgba(0, 0, 0, 0.08); /* Active pill */
132+
color: var(--accent-primary);
133+
background: rgba(255, 158, 100, 0.12);
107134
font-weight: 600;
108135
}
109136

@@ -112,6 +139,46 @@ const navLinks = [
112139
display: none;
113140
}
114141

142+
/* Theme Toggle */
143+
.theme-toggle {
144+
background: none;
145+
border: 1px solid var(--border-subtle);
146+
cursor: pointer;
147+
color: var(--fg-secondary);
148+
padding: 0.5rem;
149+
border-radius: 50%;
150+
display: flex;
151+
align-items: center;
152+
justify-content: center;
153+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
154+
margin-left: 0.5rem;
155+
}
156+
157+
.theme-toggle:hover {
158+
color: var(--accent-primary);
159+
background-color: var(--bg-card-hover);
160+
border-color: var(--accent-primary);
161+
transform: scale(1.1);
162+
box-shadow: 0 0 12px rgba(255, 158, 100, 0.3);
163+
}
164+
165+
.sun-icon {
166+
display: none;
167+
}
168+
169+
.moon-icon {
170+
display: block;
171+
}
172+
173+
/* Show sun icon in dark mode */
174+
:global([data-theme="dark"]) .sun-icon {
175+
display: block;
176+
}
177+
178+
:global([data-theme="dark"]) .moon-icon {
179+
display: none;
180+
}
181+
115182
@media (max-width: 768px) {
116183
.header-inner {
117184
flex-direction: column;
@@ -120,6 +187,12 @@ const navLinks = [
120187
gap: 1rem;
121188
}
122189

190+
.main-nav {
191+
flex-direction: column;
192+
gap: 1rem;
193+
width: 100%;
194+
}
195+
123196
.main-nav ul {
124197
gap: 0.5rem;
125198
flex-wrap: wrap;
@@ -128,7 +201,46 @@ const navLinks = [
128201
}
129202
</style>
130203

204+
<script is:inline>
205+
// Initialize theme immediately to prevent flash
206+
const theme = (() => {
207+
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
208+
return localStorage.getItem('theme');
209+
}
210+
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
211+
return 'dark';
212+
}
213+
return 'light';
214+
})();
215+
216+
if (theme === 'dark') {
217+
document.documentElement.setAttribute('data-theme', 'dark');
218+
} else {
219+
document.documentElement.removeAttribute('data-theme');
220+
}
221+
222+
window.localStorage.setItem('theme', theme);
223+
</script>
224+
131225
<script>
226+
// Toggle Logic
227+
const handleToggleClick = () => {
228+
const element = document.documentElement;
229+
const currentTheme = element.getAttribute('data-theme');
230+
const isDark = currentTheme === 'dark';
231+
232+
if (isDark) {
233+
element.removeAttribute('data-theme');
234+
localStorage.setItem('theme', 'light');
235+
} else {
236+
element.setAttribute('data-theme', 'dark');
237+
localStorage.setItem('theme', 'dark');
238+
}
239+
};
240+
241+
document.getElementById('themeToggle')?.addEventListener('click', handleToggleClick);
242+
243+
// Header Scroll Logic
132244
let lastScroll = 0;
133245
const header = document.getElementById('siteHeader');
134246

0 commit comments

Comments
 (0)