feat: site-wide dark mode (Tailwind class strategy); ThemeToggle island in header; persist preference; adjust brand-surface for dark

This commit is contained in:
2025-08-08 23:26:13 +02:00
parent a0ab66189a
commit c8c550a00b
5 changed files with 58 additions and 1 deletions

View File

@@ -0,0 +1,42 @@
import { useEffect, useState } from 'react';
export default function ThemeToggle() {
const [isDark, setIsDark] = useState(false);
useEffect(() => {
const stored = localStorage.getItem('omoluabi_theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const initial = stored ? stored === 'dark' : prefersDark;
setIsDark(initial);
document.documentElement.classList.toggle('dark', initial);
}, []);
const toggle = () => {
const next = !isDark;
setIsDark(next);
document.documentElement.classList.toggle('dark', next);
localStorage.setItem('omoluabi_theme', next ? 'dark' : 'light');
};
return (
<button
onClick={toggle}
className="inline-flex items-center gap-2 px-3 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
aria-label="Toggle color theme"
>
{isDark ? (
<>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="currentColor" viewBox="0 0 24 24"><path d="M21.64 13a1 1 0 0 0-1.05-.14 8 8 0 1 1-9.45-9.45 1 1 0 0 0-.14-2A10 10 0 1 0 23 14a1 1 0 0 0-1.36-1z"/></svg>
<span className="text-sm">Dark</span>
</>
) : (
<>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="currentColor" viewBox="0 0 24 24"><path d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.8 1.42-1.42zm10.45 14.32l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM12 4a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0V5a1 1 0 0 1 1-1zm0 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm8-5h-2a1 1 0 1 1 0-2h2a1 1 0 1 1 0 2zM4 13H2a1 1 0 1 1 0-2h2a1 1 0 1 1 0 2zm2.76 6.36l-1.42 1.42-1.79-1.8 1.41-1.41 1.8 1.79zM19.78 4.46l-1.41-1.41-1.8 1.79 1.41 1.41 1.8-1.79z"/></svg>
<span className="text-sm">Light</span>
</>
)}
</button>
);
}

View File

@@ -2,6 +2,7 @@
// src/layouts/BaseLayout.astro
import '../styles/global.css';
import '../styles/main.css';
import ThemeToggle from '../components/ThemeToggle.jsx';
export interface Props {
title?: string;
@@ -55,8 +56,11 @@ const { title = "Omoluabi Association Netherlands", description = "Preserving Ni
<a href="/contact" class="text-gray-700 hover:text-nigerian-green-600 transition-colors">Contact</a>
</div>
<!-- CTA Buttons -->
<!-- Right side controls -->
<div class="hidden md:flex items-center space-x-4">
<astro-island>
<ThemeToggle client:load />
</astro-island>
<a href="/donate" class="btn bg-gradient-to-r from-ankara-red-500 to-kente-gold-500 text-white hover:shadow-lg">
❤️ Donate
</a>

View File

@@ -17,6 +17,11 @@
--dutch-blue: #1e4785;
}
/* Dark theme tokens */
.dark {
--dutch-white: #0b0f14;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;

View File

@@ -373,6 +373,11 @@
color: #fff;
}
.dark .brand-surface {
background: radial-gradient(1200px 600px at 20% 20%, rgba(255,255,255,0.04), rgba(255,255,255,0) 60%),
linear-gradient(135deg, rgba(6, 59, 21, 0.95) 0%, rgba(23, 37, 84, 0.95) 100%);
}
/* Combined Flag Button */
.btn-combined-flag {
background: linear-gradient(135deg, var(--nigerian-green) 0%, var(--dutch-red) 33%, var(--dutch-white) 66%, var(--dutch-blue) 100%);

View File

@@ -1,6 +1,7 @@
// tailwind.config.mjs
/** @type {import('tailwindcss').Config} */
export default {
darkMode: 'class',
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {