feat: implement dark mode with theme toggle

- Add dark mode support across all components and pages
- Implement theme toggle button in navbar (desktop and mobile)
- Fix desktop theme toggle icon visibility issue
- Add dark mode color variants to all text, backgrounds and components
- Update Tailwind config to enable class-based dark mode
- Add dark mode support to prose styles for blog content
- Persist theme preference in localStorage
- Update all pages (index, bio, blog) with dark mode colors
- Optimize images (me.png and me-baby.jpg)
This commit is contained in:
Lorenzo Iovino 2026-01-09 16:20:24 +01:00
parent a6cd4bcee5
commit 5f95673d2f
16 changed files with 392 additions and 203 deletions

View file

@ -12,8 +12,11 @@
/* Typography base */
body {
@apply font-sans text-base text-gray-900;
font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
@apply font-sans text-base text-gray-900 dark:text-gray-100;
font-feature-settings:
"kern" 1,
"liga" 1,
"calt" 1;
}
/* Headings ottimizzati */
@ -23,8 +26,12 @@
h4,
h5,
h6 {
@apply font-bold;
font-feature-settings: "kern" 1, "liga" 1, "calt" 1, "ss01" 1;
@apply font-bold text-gray-900 dark:text-gray-100;
font-feature-settings:
"kern" 1,
"liga" 1,
"calt" 1,
"ss01" 1;
}
h1 {
@ -50,7 +57,11 @@
/* Link ottimizzati */
a {
@apply transition-colors duration-200;
@apply transition-colors duration-200 text-gray-800 dark:text-gray-200;
}
a:hover {
@apply text-gray-600 dark:text-gray-400;
}
/* Strong e emphasis */

View file

@ -4,6 +4,10 @@
line-height: 1.875 !important;
}
.dark .prose {
color: #d1d5db !important;
}
.prose h2 {
font-size: 2.25rem !important;
font-weight: 700 !important;
@ -16,11 +20,14 @@
padding-bottom: 1rem !important;
}
.dark .prose h2 {
color: #f3f4f6 !important;
}
.prose > h2:first-child {
margin-top: 0 !important;
}
.prose h2::after {
content: "";
position: absolute;
@ -32,6 +39,10 @@
border-radius: 2px;
}
.dark .prose h2::after {
background: linear-gradient(90deg, #f9bc2e 0%, #fbd46c 100%);
}
@media (min-width: 768px) {
.prose h2 {
font-size: 3rem !important;
@ -48,6 +59,10 @@
letter-spacing: -0.01em !important;
}
.dark .prose h3 {
color: #f3f4f6 !important;
}
@media (min-width: 768px) {
.prose h3 {
font-size: 1.875rem !important;
@ -63,6 +78,10 @@
line-height: 1.4 !important;
}
.dark .prose h4 {
color: #f3f4f6 !important;
}
@media (min-width: 768px) {
.prose h4 {
font-size: 1.5rem !important;
@ -76,6 +95,10 @@
font-weight: 400 !important;
}
.dark .prose p {
color: #d1d5db !important;
}
@media (min-width: 768px) {
.prose p {
font-size: 1.1rem !important;
@ -83,8 +106,7 @@
}
.prose > p:first-of-type {
margin-top: 1.6rem
margin-top: 1.6rem;
}
@media (min-width: 768px) {
@ -102,21 +124,38 @@
transition: all 0.2s ease !important;
}
.dark .prose a {
color: #d1d5db !important;
}
.prose a:hover {
color: #111827 !important;
text-decoration-color: #111827 !important;
}
.dark .prose a:hover {
color: #f3f4f6 !important;
text-decoration-color: #f9bc2e !important;
}
.prose strong {
font-weight: 700 !important;
color: #111827 !important;
}
.dark .prose strong {
color: #f3f4f6 !important;
}
.prose em {
font-style: italic !important;
color: #4b5563 !important;
}
.dark .prose em {
color: #9ca3af !important;
}
.prose ul,
.prose ol {
margin-top: 2rem !important;
@ -140,6 +179,10 @@
margin-bottom: 0.75rem !important;
}
.dark .prose li {
color: #d1d5db !important;
}
@media (min-width: 768px) {
.prose li {
font-size: 1.1rem !important;
@ -151,6 +194,10 @@
font-weight: 600 !important;
}
.dark .prose li::marker {
color: #9ca3af !important;
}
.prose blockquote {
border-left: 4px solid #6b7280 !important;
background-color: #f9fafb !important;
@ -163,6 +210,12 @@
line-height: 1.6 !important;
}
.dark .prose blockquote {
border-left-color: #9ca3af !important;
background-color: #374151 !important;
color: #d1d5db !important;
}
.prose code {
background-color: #f3f4f6 !important;
color: #374151 !important;
@ -170,8 +223,14 @@
border-radius: 0.375rem !important;
font-size: 1rem !important;
font-weight: 600 !important;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace !important;
font-family:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
monospace !important;
}
.dark .prose code {
background-color: #374151 !important;
color: #f3f4f6 !important;
}
.prose pre {
@ -197,6 +256,10 @@
border-width: 2px !important;
}
.dark .prose hr {
border-color: #4b5563 !important;
}
.prose img {
border-radius: 1rem !important;
margin-top: 2.5rem !important;
@ -237,6 +300,10 @@
border-bottom: 2px solid #e5e7eb !important;
}
.dark .prose thead {
border-bottom-color: #4b5563 !important;
}
.prose th {
padding: 0.75rem 1rem !important;
text-align: left !important;
@ -244,16 +311,29 @@
color: #111827 !important;
}
.dark .prose th {
color: #f3f4f6 !important;
}
.prose td {
padding: 0.75rem 1rem !important;
border-bottom: 1px solid #e5e7eb !important;
color: #374151 !important;
}
.dark .prose td {
border-bottom-color: #4b5563 !important;
color: #d1d5db !important;
}
.prose tbody tr:hover {
background-color: #f9fafb !important;
}
.dark .prose tbody tr:hover {
background-color: #374151 !important;
}
/* Image Utility Classes */
/* Float classes */
@ -363,6 +443,12 @@
word-wrap: break-word !important;
}
.dark .prose div.float-left em,
.dark .prose div.float-right em,
.dark .prose div.w-full em {
color: #9ca3af !important;
}
@media (min-width: 768px) {
.prose div.float-right em {
margin-left: 2rem !important;