feat: improve UX with performance optimizations, layout fixes, and dark mode prompt

This commit is contained in:
Lorenzo Iovino 2026-01-09 17:03:17 +01:00
parent 52f112568c
commit 5c1d532386
7 changed files with 142 additions and 17 deletions

View file

@ -7,7 +7,7 @@ import githubIcon from "../assets/github.svg";
<div class="w-full"> <div class="w-full">
<div class="relative px-6 lg:px-8"> <div class="relative px-6 lg:px-8">
<div class="mx-auto max-w-5xl"> <div class="mx-auto max-w-6xl">
<div <div
class="relative overflow-hidden rounded-3xl bg-white dark:bg-gray-800 shadow-soft-lg hover:shadow-soft-lg transition-all duration-300" class="relative overflow-hidden rounded-3xl bg-white dark:bg-gray-800 shadow-soft-lg hover:shadow-soft-lg transition-all duration-300"
style="min-height: 300px;" style="min-height: 300px;"
@ -38,7 +38,7 @@ import githubIcon from "../assets/github.svg";
<div class="space-y-4 md:space-y-6"> <div class="space-y-4 md:space-y-6">
<!-- Greeting --> <!-- Greeting -->
<div class="text-center md:text-left"> <div class="text-center md:text-left">
<h1 class="mb-3 text-gray-900 dark:text-gray-100" style="min-height: 2.5rem;"> <h1 class="mb-3 pb-2 text-gray-900 dark:text-gray-100" style="min-height: 2.5rem;">
Hey, I'm <span class="text-gray-900 dark:text-gray-100 font-extrabold" Hey, I'm <span class="text-gray-900 dark:text-gray-100 font-extrabold"
>Lorenzo</span >Lorenzo</span
>! >!

View file

@ -222,5 +222,130 @@ const fullCanonicalUrl = canonicalUrl || `${siteUrl}${Astro.url.pathname}`;
</head> </head>
<body class="bg-white dark:bg-gray-900 min-h-screen transition-colors duration-200"> <body class="bg-white dark:bg-gray-900 min-h-screen transition-colors duration-200">
<slot /> <slot />
<!-- Dark Mode Suggestion Toast -->
<div
id="dark-mode-toast"
class="hidden fixed bottom-6 right-6 bg-white dark:bg-gray-800 shadow-2xl rounded-xl p-4 max-w-sm border border-gray-200 dark:border-gray-700 z-50 transition-all duration-300 transform translate-y-0"
style="animation: slideUp 0.3s ease-out;"
>
<div class="flex items-start gap-3">
<div class="flex-shrink-0 mt-0.5">
<svg
class="w-5 h-5 text-gray-700 dark:text-gray-300"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
></path>
</svg>
</div>
<div class="flex-1">
<p class="text-sm font-medium text-gray-900 dark:text-gray-100 mb-1">Try Dark Mode?</p>
<p class="text-xs text-gray-600 dark:text-gray-400 mb-3">
Experience the site in a beautiful dark theme
</p>
<div class="flex gap-2">
<button
id="try-dark-mode"
class="px-3 py-1.5 bg-gray-900 text-white text-xs font-medium rounded-lg hover:bg-gray-800 transition-colors"
>
Enable
</button>
<button
id="dismiss-toast"
class="px-3 py-1.5 bg-gray-100 text-gray-700 text-xs font-medium rounded-lg hover:bg-gray-200 transition-colors"
>
Maybe later
</button>
</div>
</div>
<button
id="close-toast"
class="flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors"
aria-label="Close"
>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
</div>
<style>
@keyframes slideUp {
from {
transform: translateY(100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
</style>
<script is:inline>
// Dark mode suggestion toast
(function () {
const TOAST_DISMISSED_KEY = "darkModeToastDismissed";
const toast = document.getElementById("dark-mode-toast");
const tryButton = document.getElementById("try-dark-mode");
const dismissButton = document.getElementById("dismiss-toast");
const closeButton = document.getElementById("close-toast");
// Check if user has already dismissed the toast
const hasBeenDismissed = localStorage.getItem(TOAST_DISMISSED_KEY);
// Only show toast if user is in light mode and hasn't dismissed it
setTimeout(() => {
const isDarkMode = document.documentElement.classList.contains("dark");
if (!isDarkMode && !hasBeenDismissed && toast) {
toast.classList.remove("hidden");
}
}, 2000);
// Enable dark mode
if (tryButton) {
tryButton.addEventListener("click", () => {
document.documentElement.classList.add("dark");
localStorage.setItem("theme", "dark");
localStorage.setItem(TOAST_DISMISSED_KEY, "true");
toast?.classList.add("hidden");
// Update theme toggle icons
const darkIcons = document.querySelectorAll(".theme-toggle-dark-icon");
const lightIcons = document.querySelectorAll(".theme-toggle-light-icon");
darkIcons.forEach((icon) => icon.classList.add("hidden"));
lightIcons.forEach((icon) => icon.classList.remove("hidden"));
});
}
// Dismiss toast
if (dismissButton) {
dismissButton.addEventListener("click", () => {
localStorage.setItem(TOAST_DISMISSED_KEY, "true");
toast?.classList.add("hidden");
});
}
// Close toast
if (closeButton) {
closeButton.addEventListener("click", () => {
localStorage.setItem(TOAST_DISMISSED_KEY, "true");
toast?.classList.add("hidden");
});
}
})();
</script>
</body> </body>
</html> </html>

View file

@ -25,7 +25,7 @@ const { Content } = await bioEntry.render();
<div class="min-h-screen pt-16 bg-secondary dark:bg-gray-900 transition-colors duration-200"> <div class="min-h-screen pt-16 bg-secondary dark:bg-gray-900 transition-colors duration-200">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12 md:py-20"> <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12 md:py-20">
<div class="mb-16 text-center"> <div class="mb-16 text-center">
<h1 class="text-gray-800 dark:text-gray-100 mb-4">{bioEntry.data.title}</h1> <h1 class="text-gray-800 dark:text-gray-100 mb-4 pb-2">{bioEntry.data.title}</h1>
<p class="text-xl text-gray-700 dark:text-gray-300 max-w-2xl mx-auto"> <p class="text-xl text-gray-700 dark:text-gray-300 max-w-2xl mx-auto">
{bioEntry.data.description} {bioEntry.data.description}
</p> </p>

View file

@ -34,9 +34,9 @@ const initialPosts: BlogPost[] = sortedPosts.slice(0, 6);
<BaseLayout title="Lorenzo Iovino >> Blog" description="Blog posts and articles by Lorenzo Iovino"> <BaseLayout title="Lorenzo Iovino >> Blog" description="Blog posts and articles by Lorenzo Iovino">
<Navbar /> <Navbar />
<div class="min-h-screen pt-16 bg-secondary dark:bg-gray-900 transition-colors duration-200"> <div class="min-h-screen pt-16 bg-secondary dark:bg-gray-900 transition-colors duration-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 md:py-20"> <div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-12 md:py-20">
<div class="mb-16 text-center"> <div class="mb-16 text-center">
<h1 class="text-gray-800 dark:text-gray-100 mb-4">Blog</h1> <h1 class="text-gray-800 dark:text-gray-100 mb-4 pb-2">Blog</h1>
<p class="text-xl text-gray-800/90 dark:text-gray-300 max-w-2xl mx-auto"> <p class="text-xl text-gray-800/90 dark:text-gray-300 max-w-2xl mx-auto">
Thoughts, experiences, and insights about software engineering, technology, and life Thoughts, experiences, and insights about software engineering, technology, and life
</p> </p>

View file

@ -65,7 +65,7 @@ const heroImageSrc = entry.data.heroImage?.src || mePhoto.src;
) )
} }
<h1 <h1
class="text-gray-900 dark:text-gray-100 mb-4 text-3xl md:text-4xl lg:text-5xl font-bold leading-tight" class="text-gray-900 dark:text-gray-100 mb-4 text-4xl md:text-5xl lg:text-5xl font-bold leading-normal pb-2"
> >
{entry.data.title} {entry.data.title}
</h1> </h1>
@ -105,26 +105,26 @@ const heroImageSrc = entry.data.heroImage?.src || mePhoto.src;
<div <div
class="mt-8 md:mt-12 bg-white dark:bg-gray-800 rounded-xl md:rounded-2xl shadow-lg p-6 sm:p-8 transition-colors duration-200" class="mt-8 md:mt-12 bg-white dark:bg-gray-800 rounded-xl md:rounded-2xl shadow-lg p-6 sm:p-8 transition-colors duration-200"
> >
<div class="flex items-start gap-6"> <div class="flex flex-col sm:flex-row items-center gap-4 sm:gap-6">
<Image <Image
src={mePhoto} src={mePhoto}
alt="Lorenzo Iovino" alt="Lorenzo Iovino"
class="w-20 h-20 rounded-full object-cover" class="w-20 h-20 rounded-full object-cover flex-shrink-0"
width={80} width={80}
height={80} height={80}
quality={90} quality={90}
format="webp" format="webp"
/> />
<div> <div class="text-center sm:text-left">
<h3 class="text-lg md:text-xl font-bold text-gray-900 dark:text-gray-100 mb-2"> <h3 class="text-lg md:text-xl font-bold text-gray-900 dark:text-gray-100 mb-2">
Lorenzo Iovino Lorenzo Iovino
</h3> </h3>
<p class="text-sm md:text-base text-gray-700 dark:text-gray-300 mb-4"> <p class="text-sm md:text-base text-gray-700 dark:text-gray-300 mb-4">
Software Engineer based in Sicily, passionate about technology, remote work, and life I write software and I also work on a small vineyard in Sicily. In code, trees grow
balance. When not coding, you'll find me working on my vineyard or exploring the downward from the root. In real life, trees grow upward from the roots. I spend way
beautiful Sicilian countryside. too much time thinking about this.
</p> </p>
<div class="flex gap-4"> <div class="flex gap-4 justify-center sm:justify-start">
<a <a
href="https://www.linkedin.com/in/lorenzoiovino/" href="https://www.linkedin.com/in/lorenzoiovino/"
target="_blank" target="_blank"

View file

@ -53,11 +53,11 @@
} }
h2 { h2 {
@apply text-3xl md:text-4xl lg:text-5xl; @apply text-2xl md:text-3xl lg:text-4xl;
} }
h3 { h3 {
@apply text-2xl md:text-3xl; @apply text-xl md:text-2xl lg:text-3xl;
} }
h4 { h4 {

View file

@ -9,7 +9,7 @@
} }
.prose h2 { .prose h2 {
font-size: 2.25rem !important; font-size: 1.875rem !important;
font-weight: 700 !important; font-weight: 700 !important;
color: #111827 !important; color: #111827 !important;
margin-top: 3rem !important; margin-top: 3rem !important;
@ -45,7 +45,7 @@
@media (min-width: 768px) { @media (min-width: 768px) {
.prose h2 { .prose h2 {
font-size: 3rem !important; font-size: 2rem !important;
} }
} }