diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..b088c15
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,22 @@
+# CLAUDE.md - Guidance for AI Assistance
+
+## Build & Workflow Commands
+- Development: `npm run dev`
+- Build: `npm run build`
+- Start production: `npm run start`
+- Lint: `npm run lint`
+
+## Code Style Guidelines
+- **Components**: Named function exports with "use client" directive where needed
+- **TypeScript**: Strict mode, explicit types for props and functions
+- **Naming**: PascalCase for components, camelCase for functions/variables
+- **Imports**: React → Next.js → external → internal, use path aliases (@/components, @/lib)
+- **Styling**: Tailwind CSS with utility classes, use `cn()` for conditional classes
+- **UI Components**: Reusable components in components/ui with consistent prop interfaces
+- **Formatting**: 2-space indentation, consistent spacing, trailing commas
+- **Error Handling**: Use try/catch for async operations, provide meaningful error messages
+
+## Project Structure
+- `/src/app`: Next.js App Router pages and layouts
+- `/src/components`: Reusable React components, UI components in `/ui`
+- `/src/lib`: Utility functions and helpers
\ No newline at end of file
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index d55a7cd..cc3d35b 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,6 +1,7 @@
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
+import { ThemeProvider } from '@/components/ui/theme-provider'
const inter = Inter({ subsets: ['latin'] })
@@ -15,9 +16,16 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
-
+
- {children}
+
+ {children}
+
)
diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx
index e92c107..f7c929c 100644
--- a/src/components/navbar.tsx
+++ b/src/components/navbar.tsx
@@ -2,6 +2,7 @@
import Link from "next/link"
import { Button } from "@/components/ui/button"
+import { ThemeToggle } from "@/components/ui/theme-toggle"
import { motion } from "framer-motion"
function Navbar() {
@@ -33,6 +34,7 @@ function Navbar() {
+
diff --git a/src/components/ui/theme-provider.tsx b/src/components/ui/theme-provider.tsx
new file mode 100644
index 0000000..e740035
--- /dev/null
+++ b/src/components/ui/theme-provider.tsx
@@ -0,0 +1,97 @@
+"use client"
+
+import * as React from "react"
+import { getSystemTheme, isBrowser, type Theme } from "@/lib/utils"
+
+type ThemeProviderProps = {
+ children: React.ReactNode
+ defaultTheme?: Theme
+ storageKey?: string
+ attribute?: string
+ enableSystem?: boolean
+ disableTransitionOnChange?: boolean
+}
+
+type ThemeProviderState = {
+ theme: Theme
+ setTheme: (theme: Theme) => void
+}
+
+const initialState: ThemeProviderState = {
+ theme: "system",
+ setTheme: () => null,
+}
+
+export const ThemeProviderContext = React.createContext(initialState)
+
+export function ThemeProvider({
+ children,
+ defaultTheme = "system",
+ storageKey = "theme",
+ ...props
+}: ThemeProviderProps) {
+ const [theme, setTheme] = React.useState(
+ () => {
+ if (!isBrowser) return defaultTheme
+ return (localStorage.getItem(storageKey) as Theme) || defaultTheme
+ }
+ )
+
+ React.useEffect(() => {
+ const root = window.document.documentElement
+
+ // Remove old class
+ root.classList.remove("light", "dark")
+
+ // Add new class based on theme
+ if (theme === "system") {
+ const systemTheme = getSystemTheme()
+ root.classList.add(systemTheme)
+ } else {
+ root.classList.add(theme)
+ }
+ }, [theme])
+
+ // Monitor for system theme change
+ React.useEffect(() => {
+ if (theme !== "system") return
+
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
+
+ const handleChange = () => {
+ const root = window.document.documentElement
+ const systemTheme = getSystemTheme()
+
+ root.classList.remove("light", "dark")
+ root.classList.add(systemTheme)
+ }
+
+ mediaQuery.addEventListener("change", handleChange)
+ return () => mediaQuery.removeEventListener("change", handleChange)
+ }, [theme])
+
+ const value = React.useMemo(
+ () => ({
+ theme,
+ setTheme: (newTheme: Theme) => {
+ localStorage.setItem(storageKey, newTheme)
+ setTheme(newTheme)
+ },
+ }),
+ [theme, storageKey]
+ )
+
+ return (
+
+ {children}
+
+ )
+}
+
+// Hook to use the theme context
+export const useTheme = () => {
+ const context = React.useContext(ThemeProviderContext)
+ if (context === undefined)
+ throw new Error("useTheme must be used within a ThemeProvider")
+ return context
+}
\ No newline at end of file
diff --git a/src/components/ui/theme-toggle.tsx b/src/components/ui/theme-toggle.tsx
new file mode 100644
index 0000000..9ee7dfe
--- /dev/null
+++ b/src/components/ui/theme-toggle.tsx
@@ -0,0 +1,25 @@
+"use client"
+
+import * as React from "react"
+import { Moon, Sun } from "lucide-react"
+
+import { useTheme } from "@/components/ui/theme-provider"
+import { Button } from "@/components/ui/button"
+
+export function ThemeToggle() {
+ const { theme, setTheme } = useTheme()
+
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index f7654e8..c340e04 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -3,4 +3,15 @@ import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
-}
\ No newline at end of file
+}
+
+// Check if we're running in the browser
+export const isBrowser = typeof window !== 'undefined'
+
+// Theme utilities
+export type Theme = 'dark' | 'light' | 'system'
+
+export function getSystemTheme(): Theme {
+ if (!isBrowser) return 'light'
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
+}
\ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
index 626f9b8..682d40c 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,5 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
+ darkMode: ["class"],
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',