11---
2- import { LOGO_IMAGE , SITE } from " @config" ;
3- import Hr from " ./Hr.astro" ;
2+ import { SITE } from " @config" ;
43import LinkButton from " ./LinkButton.astro" ;
4+ import Separator from " ./Separator.astro" ;
55
66export interface Props {
77 activeNav? :
@@ -17,26 +17,22 @@ export interface Props {
1717const { activeNav } = Astro .props ;
1818---
1919
20- <header >
21- <a id =" skip-to-content" href =" #main-content" >Skip to content</a >
20+ <header class =" glass sticky top-0 z-30 w-full transition-all duration-300" >
2221 <div class =" nav-container" >
2322 <div class =" top-nav-wrap" >
2423 <a
2524 href =" /"
2625 class ={ ` logo whitespace-nowrap ${activeNav === " home" ? " active" : " " } ` }
2726 >
28- {
29- LOGO_IMAGE .enable ? (
30- <img
31- src = { ` /assets/${LOGO_IMAGE .svg ? " logo.svg" : " logo.png" } ` }
32- alt = { SITE .title }
33- width = { LOGO_IMAGE .width }
34- height = { LOGO_IMAGE .height }
35- />
36- ) : (
37- <span id = " typewriter-text" >{ SITE .title } </span >
38- )
39- }
27+ <span
28+ class =" flex items-center gap-0.5 font-mono text-xl font-bold tracking-tight sm:text-xl"
29+ >
30+ <span class =" text-skin-accent" >Dev</span ><span class =" text-skin-base"
31+ >@</span
32+ ><span class =" text-skin-terminal-green" >Machine</span ><span
33+ class =" text-skin-base" >:~$</span
34+ ><span class =" animate-blink text-skin-accent" >_</span >
35+ </span >
4036 </a >
4137 <nav id =" nav-menu" >
4238 <button
@@ -64,7 +60,7 @@ const { activeNav } = Astro.props;
6460 <line x1 =" 6" y1 =" 6" x2 =" 18" y2 =" 18" class =" close" ></line >
6561 </svg >
6662 </button >
67- <ul id =" menu-items" class =" display-none sm:flex" >
63+ <ul id =" menu-items" class =" display-none list-none sm:flex" >
6864 <li >
6965 <a href =" /posts/" class ={ activeNav === " posts" ? " active" : " " } >
7066 Posts
@@ -123,7 +119,7 @@ const { activeNav } = Astro.props;
123119 aria-live = " polite"
124120 >
125121 <svg xmlns = " http://www.w3.org/2000/svg" id = " moon-svg" >
126- <path d = " M20.742 13.045a8.088 8.088 0 0 1-2.077.271c-2.135 0-4.14-.83-5.646-2.336a8.025 8.025 0 0 1-2.064-7.723A1 1 0 0 0 9.73 2.034a10.014 10.014 0 0 0-4.489 2.582c-3.898 3.898-3.898 10.243 0 14.143a9.937 9.937 0 0 0 7.072 2.93 9.93 9.93 0 0 0 7.07-2.929 10.007 10.007 0 0 0 2.583-4.491 1.001 1.001 0 0 0-1.224-1.224zm-2.772 4.301a7.947 7.947 0 0 1-5.656 2.343 7.953 7.953 0 0 1-5.658-2.344c-3.118-3.119-3.118-8.195 0-11.314a7.923 7.923 0 0 1 2.06-1.483 10.027 10.027 0 0 0 2.89 7.848 9.972 9.972 0 0 0 7.848 2.891 8.036 8.036 0 0 1-1.484 2.059z" />
122+ <path d = " M20.742 13.045a8.088 8.088 0 0 1-2.077.271c-2.135 0-4.14-.83-5.646-2.336a8.025 8.025 0 0 1-2.064-7.723A1 1 0 0 0 9.73 2.034a10.014 10.014 0 0 0-4.489 2.582c-3.898 3.898-3.898 10.243 0 14.143a9.937 9.937 0 0 0 7.072 2.93 9.93 0 0 0 7.07-2.929 10.007 10.007 0 0 0 2.583-4.491 1.001 1.001 0 0 0-1.224-1.224zm-2.772 4.301a7.947 7.947 0 0 1-5.656 2.343 7.953 7.953 0 0 1-5.658-2.344c-3.118-3.119-3.118-8.195 0-11.314a7.923 7.923 0 0 1 2.06-1.483 10.027 10.027 0 0 0 2.89 7.848 9.972 9.972 0 0 0 7.848 2.891 8.036 8.036 0 0 1-1.484 2.059z" />
127123 </svg >
128124 <svg xmlns = " http://www.w3.org/2000/svg" id = " sun-svg" >
129125 <path d = " M6.993 12c0 2.761 2.246 5.007 5.007 5.007s5.007-2.246 5.007-5.007S14.761 6.993 12 6.993 6.993 9.239 6.993 12zM12 8.993c1.658 0 3.007 1.349 3.007 3.007S13.658 15.007 12 15.007 8.993 13.658 8.993 12 10.342 8.993 12 8.993zM10.998 19h2v3h-2zm0-17h2v3h-2zm-9 9h3v2h-3zm17 0h3v2h-3zM4.219 18.363l2.12-2.122 1.415 1.414-2.12 2.122zM16.24 6.344l2.122-2.122 1.414 1.414-2.122 2.122zM6.342 7.759 4.22 5.637l1.415-1.414 2.12 2.122zm13.434 10.605-1.414 1.414-2.122-2.122 1.414-1.414z" />
@@ -136,37 +132,30 @@ const { activeNav } = Astro.props;
136132 </nav >
137133 </div >
138134 </div >
139- <Hr />
140135</header >
136+ <Separator />
141137
142138<style >
143- #skip-to-content {
139+ /* #skip-to-content {
144140 @apply absolute -top-full left-16 z-50 bg-skin-accent px-3 py-2 text-skin-inverted transition-all focus:top-4;
145- }
141+ } */
146142 .nav-container {
147- @apply mx-auto flex max-w-3xl flex-col items-center justify-between sm:flex-row;
143+ @apply mx-auto flex max-w-5xl flex-col items-center justify-between sm:flex-row;
148144 }
149145 .top-nav-wrap {
150- @apply relative flex w-full items-start justify-between p-4 sm:items-center sm:py-8 ;
146+ @apply relative flex w-full items-start justify-between p-4 sm:items-center sm:py-4 ;
151147 }
152148 .logo {
153- @apply absolute py-1 text-xl font-semibold sm:static sm:text-2xl ;
149+ @apply absolute py-1 text-xl font-semibold sm:static sm:text-xl ;
154150 }
155151 /* .logo.active {
156152 @apply underline decoration-wavy decoration-2 underline-offset-4 decoration-skin-accent;
157153 } */
158- .hamburger-menu {
159- @apply self-end p-2 sm:hidden;
160- }
161- .hamburger-menu svg {
162- @apply h-6 w-6 scale-125 fill-skin-base;
163- }
164-
165154 nav {
166155 @apply flex w-full flex-col items-center sm:ml-2 sm:flex-row sm:justify-end sm:space-x-4 sm:py-0;
167156 }
168157 nav ul {
169- @apply mt-4 grid w-44 grid-cols-2 grid-rows-4 gap-x-2 gap-y-2 sm:ml-0 sm:mt-0 sm:w-auto sm:gap-x-5 sm:gap-y-0;
158+ @apply mt-4 grid w-44 grid-cols-2 gap-x-2 gap-y-2 sm:ml-0 sm:mt-0 sm:w-auto sm:gap-x-5 sm:gap-y-0;
170159 }
171160 nav ul li {
172161 @apply col-span-2 flex items-center justify-center;
@@ -182,7 +171,7 @@ const { activeNav } = Astro.props;
182171 @apply col-span-1;
183172 }
184173 nav a.active {
185- @apply underline decoration-wavy decoration-2 underline-offset-4;
174+ @apply underline decoration-skin-accent decoration- wavy decoration-2 underline-offset-4;
186175 }
187176 nav a.active svg {
188177 @apply fill-skin-accent;
@@ -201,27 +190,29 @@ const { activeNav } = Astro.props;
201190 @apply scale-125 hover:rotate-12 sm:scale-100;
202191 }
203192
193+ .hamburger-menu {
194+ @apply self-end p-2 sm:hidden;
195+ }
196+ .menu-icon {
197+ @apply h-6 w-6 scale-125 fill-skin-base text-skin-base;
198+ }
204199 .menu-icon line {
205200 @apply transition-opacity duration-75 ease-in-out;
206201 }
207202 .menu-icon .close {
208203 opacity: 0;
209204 }
210- .menu-icon.is-active . line {
211- @apply opacity- 0;
205+ .menu-icon.is-active line {
206+ opacity: 0;
212207 }
213208 .menu-icon.is-active .close {
214- @apply opacity-100 ;
209+ opacity: 1 ;
215210 }
216-
217- /* Typewriter Cursor */
218- .logo span::after {
219- content: "|";
220- animation: cursor 1s infinite step-start;
221- @apply ml-1 font-light text-skin-accent;
211+ .active {
212+ @apply text-skin-accent;
222213 }
223214
224- @keyframes cursor {
215+ @keyframes blink {
225216 0%,
226217 100% {
227218 opacity: 1;
@@ -230,18 +221,20 @@ const { activeNav } = Astro.props;
230221 opacity: 0;
231222 }
232223 }
224+ .animate-blink {
225+ animation: blink 1s infinite step-start;
226+ }
233227</style >
234228
235229<script >
236230 function toggleNav() {
237231 // Toggle menu
238232 const menuBtn = document.querySelector(".hamburger-menu");
239- const menuIcon = document.querySelector(".menu-icon");
240233 const menuItems = document.querySelector("#menu-items");
241234
242235 menuBtn?.addEventListener("click", () => {
243236 const menuExpanded = menuBtn.getAttribute("aria-expanded") === "true";
244- menuIcon? .classList.toggle("is-active");
237+ menuBtn .classList.toggle("is-active");
245238 menuBtn.setAttribute("aria-expanded", menuExpanded ? "false" : "true");
246239 menuBtn.setAttribute(
247240 "aria-label",
@@ -255,87 +248,4 @@ const { activeNav } = Astro.props;
255248
256249 // Runs on view transitions navigation
257250 document.addEventListener("astro:after-swap", toggleNav);
258-
259- // Typewriter Animation
260- function typewriter() {
261- const typewriterTextElement = document.getElementById("typewriter-text");
262- if (!typewriterTextElement) return;
263-
264- const words = ["Devadathan", "Dev"];
265- let wordIndex = 0; // 0 for "Devadathan", 1 for "Dev"
266- let charIndex = words[wordIndex].length; // Start with the full initial word
267- let isDeleting = true; // Start by deleting the initial word
268- let typingSpeed = 150;
269-
270- function type() {
271- // Ensure element still exists, especially important for SPA transitions
272- if (!typewriterTextElement) return;
273-
274- const currentWord = words[wordIndex];
275- const targetWord = words[(wordIndex + 1) % words.length]; // The word we're transitioning to
276-
277- if (isDeleting) {
278- typewriterTextElement.textContent = currentWord.substring(
279- 0,
280- charIndex - 1
281- );
282- charIndex--;
283- typingSpeed = 75; // Faster deleting
284- } else {
285- typewriterTextElement.textContent = targetWord.substring(
286- 0,
287- charIndex + 1
288- );
289- charIndex++;
290- typingSpeed = 150; // Normal typing
291- }
292-
293- // Logic for switching between deleting and typing
294-
295- if (isDeleting && charIndex === (wordIndex === 0 ? words[1].length : 0)) {
296- if (wordIndex === 0) {
297- // Finished deleting "Devadathan" down to "Dev"
298- isDeleting = false; // Start typing
299- wordIndex = 1; // Now target "Devadathan" (next word in cycle)
300- typingSpeed = 1500; // Pause before typing
301-
302- typewriterTextElement.classList.add("italic");
303- } else {
304- // Finished deleting "Dev" down to nothing
305- isDeleting = false; // Start typing
306- wordIndex = 0; // Now target "Devadathan"
307- typingSpeed = 500; // Pause before typing
308-
309- typewriterTextElement.classList.remove("italic");
310- }
311- } else if (!isDeleting && charIndex === targetWord.length) {
312- // Finished typing a word
313- isDeleting = true; // Start deleting
314- wordIndex = (wordIndex + 1) % words.length; // Move to the next word to delete
315- charIndex = targetWord.length; // Set charIndex to full length for deletion
316- typingSpeed = 1500; // Pause at end of word
317-
318- // Ensure italics are removed if we just finished typing Devadathan
319- if (wordIndex === 0) {
320- typewriterTextElement.classList.remove("italic");
321- }
322- }
323-
324- setTimeout(type, typingSpeed);
325- }
326-
327- // Initial call after a short delay to allow content to render
328- // and to simulate a pause before the first deletion
329- setTimeout(() => {
330- if (typewriterTextElement) {
331- // Check again in case element was removed during delay
332- type();
333- }
334- }, 1500); // Initial pause before starting the animation
335- }
336-
337- // Call typewriter on initial load
338- typewriter();
339- // Call typewriter on view transitions navigation
340- document.addEventListener("astro:after-swap", typewriter);
341251</script >
0 commit comments