Skip to content

Commit af8e5e4

Browse files
committed
feat: Minor tweaks
1 parent c2cd36d commit af8e5e4

File tree

9 files changed

+168
-219
lines changed

9 files changed

+168
-219
lines changed

src/components/Card.tsx

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,34 @@ export default function Card({ href, frontmatter, secHeading = true }: Props) {
1919

2020
return (
2121
<li className="my-6">
22-
<a
23-
href={href}
24-
className="inline-block text-lg font-medium text-skin-accent decoration-dashed underline-offset-4 focus-visible:no-underline focus-visible:underline-offset-0"
25-
>
26-
{secHeading ? (
27-
<h2 {...headerProps}>{title}</h2>
28-
) : (
29-
<h3 {...headerProps}>{title}</h3>
30-
)}
31-
</a>
32-
<Datetime
33-
pubDatetime={pubDatetime}
34-
modDatetime={modDatetime}
35-
readingTime={readingTime}
36-
/>
37-
<p>{description}</p>
22+
<div className="group relative rounded-xl border border-transparent bg-transparent p-4 transition-all hover:border-skin-line/50 hover:bg-skin-card/50 hover:shadow-lg hover:backdrop-blur-sm">
23+
<a
24+
href={href}
25+
className="inline-block text-lg font-medium text-skin-accent decoration-dashed underline-offset-4 focus-visible:no-underline focus-visible:underline-offset-0"
26+
>
27+
{secHeading ? (
28+
<h2
29+
{...headerProps}
30+
className="text-xl font-bold text-skin-accent group-hover:text-skin-accent"
31+
>
32+
{title}
33+
</h2>
34+
) : (
35+
<h3
36+
{...headerProps}
37+
className="text-xl font-bold text-skin-accent group-hover:text-skin-accent"
38+
>
39+
{title}
40+
</h3>
41+
)}
42+
</a>
43+
<Datetime
44+
pubDatetime={pubDatetime}
45+
modDatetime={modDatetime}
46+
readingTime={readingTime}
47+
/>
48+
<p className="mt-2 text-skin-base opacity-90">{description}</p>
49+
</div>
3850
</li>
3951
);
4052
}

src/components/Footer.astro

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
import Hr from "./Hr.astro";
32
import Socials from "./Socials.astro";
3+
import Separator from "./Separator.astro";
44
55
const currentYear = new Date().getFullYear();
66
const commitHash = import.meta.env.GIT_COMMIT_HASH || "unknown";
@@ -14,7 +14,7 @@ const { noMarginTop = false } = Astro.props;
1414
---
1515

1616
<footer class={`${noMarginTop ? "" : "mt-auto"}`}>
17-
<Hr noPadding />
17+
<Separator noPadding />
1818
<div class="mx-auto max-w-3xl px-4">
1919
<div class="footer-wrapper">
2020
<Socials centered />
@@ -38,25 +38,25 @@ const { noMarginTop = false } = Astro.props;
3838

3939
<style>
4040
footer {
41-
@apply w-full;
41+
@apply mt-auto w-full bg-skin-fill/50 backdrop-blur-sm;
4242
}
4343
.footer-wrapper {
44-
@apply flex flex-col items-center justify-between py-6 sm:flex-row-reverse sm:py-4;
44+
@apply flex flex-col items-center justify-between py-8 sm:flex-row-reverse sm:py-6;
4545
}
4646
.link-button {
47-
@apply my-1 p-2 hover:rotate-6;
47+
@apply my-1 p-2 transition-transform hover:rotate-6;
4848
}
4949
.link-button svg {
5050
@apply scale-125;
5151
}
5252
.copyright-wrapper {
53-
@apply my-2 flex flex-col items-center whitespace-nowrap sm:flex-row;
53+
@apply my-2 flex flex-col items-center whitespace-nowrap text-sm opacity-80 sm:flex-row;
5454
}
5555
.separator {
5656
@apply hidden sm:inline;
5757
}
5858
.deploy-info {
59-
@apply pb-4 text-center text-sm opacity-60 transition-opacity hover:opacity-80;
59+
@apply pb-6 text-center text-sm opacity-70 transition-opacity hover:opacity-100;
6060
}
6161
.commit-link {
6262
@apply font-mono underline decoration-dashed underline-offset-2 transition-all hover:decoration-solid;

src/components/Header.astro

Lines changed: 38 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
import { LOGO_IMAGE, SITE } from "@config";
3-
import Hr from "./Hr.astro";
2+
import { SITE } from "@config";
43
import LinkButton from "./LinkButton.astro";
4+
import Separator from "./Separator.astro";
55
66
export interface Props {
77
activeNav?:
@@ -17,26 +17,22 @@ export interface Props {
1717
const { 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>

src/components/Separator.astro

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
export interface Props {
3+
noPadding?: boolean;
4+
className?: string;
5+
}
6+
7+
const { noPadding = false, className = "" } = Astro.props;
8+
---
9+
10+
<div class={`mx-auto max-w-5xl ${noPadding ? "px-0" : "px-4"} ${className}`}>
11+
<div
12+
class="h-[1px] w-full bg-gradient-to-r from-transparent via-[rgb(var(--color-border))] to-transparent opacity-75"
13+
>
14+
</div>
15+
</div>

src/layouts/Layout.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ const socialImageURL = new URL(
8888
<link rel="preconnect" href="https://fonts.googleapis.com" />
8989
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9090
<link
91-
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400;1,600&family=JetBrains+Mono:wght@400;500;600;700&display=swap"
91+
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap"
9292
rel="stylesheet"
9393
/>
9494

0 commit comments

Comments
 (0)