Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
--background: #ffffff;
}

@media (prefers-color-scheme: dark) {
:root {
--foreground: #ededed;
--background: #0a0a0a;
}
/* Dark mode via class (controlled by ThemeToggle) */
.dark {
--foreground: #ededed;
--background: #0a0a0a;
}

body {
color: var(--foreground);
background: var(--background);
transition: background-color 0.2s ease, color 0.2s ease;
}
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export default function RootLayout({
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className="min-h-screen bg-gray-50">
<html lang="en" suppressHydrationWarning>
<body className="min-h-screen bg-gray-50 dark:bg-gray-950 transition-colors">
<Providers>{children}</Providers>
</body>
</html>
Expand Down
6 changes: 5 additions & 1 deletion src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import Link from "next/link";
import { ConnectWallet } from "./ConnectWallet";
import { ThemeToggle } from "./ThemeToggle";

export function Navbar() {
return (
Expand All @@ -27,7 +28,10 @@ export function Navbar() {
</Link>
</div>
</div>
<ConnectWallet />
<div className="flex items-center gap-2">
<ThemeToggle />
<ConnectWallet />
</div>
</div>
</div>
</nav>
Expand Down
43 changes: 43 additions & 0 deletions src/components/ThemeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";

import { useEffect, useState } from "react";

export function ThemeToggle() {
const [dark, setDark] = useState(false);

// On mount, read saved preference or system preference
useEffect(() => {
const saved = localStorage.getItem("sorosave-theme");
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const isDark = saved ? saved === "dark" : prefersDark;
setDark(isDark);
document.documentElement.classList.toggle("dark", isDark);
}, []);

const toggle = () => {
const next = !dark;
setDark(next);
document.documentElement.classList.toggle("dark", next);
localStorage.setItem("sorosave-theme", next ? "dark" : "light");
};

return (
<button
onClick={toggle}
aria-label="Toggle dark mode"
className="rounded-lg p-2 text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
>
{dark ? (
/* Sun icon */
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364-6.364l-.707.707M6.343 17.657l-.707.707M17.657 17.657l-.707-.707M6.343 6.343l-.707-.707M12 8a4 4 0 100 8 4 4 0 000-8z" />
</svg>
) : (
/* Moon icon */
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M21 12.79A9 9 0 1111.21 3a7 7 0 009.79 9.79z" />
</svg>
)}
</button>
);
}