Overview
The portfolio uses a sophisticated theme system built with React Context API, supporting both light and dark modes with persistent user preferences. The theme is powered by CSS custom properties and Tailwind CSS.
Theme System Architecture
ThemeContext
The theme is managed through a React Context located at src/contexts/ThemeContext.jsx:
src/contexts/ThemeContext.jsx
import React , { createContext , useContext , useEffect , useState } from 'react' ;
const ThemeContext = createContext ();
export const useTheme = () => {
const context = useContext ( ThemeContext );
if ( ! context ) {
throw new Error ( 'useTheme must be used within ThemeProvider' );
}
return context ;
};
export const ThemeProvider = ({ children }) => {
const [ isDark , setIsDark ] = useState (() => {
const saved = localStorage . getItem ( 'theme' );
return saved ? saved === 'dark' : true ; // Default to dark
});
useEffect (() => {
localStorage . setItem ( 'theme' , isDark ? 'dark' : 'light' );
document . documentElement . classList . toggle ( 'dark' , isDark );
}, [ isDark ]);
const toggleTheme = () => setIsDark ( ! isDark );
return (
< ThemeContext.Provider value = { { isDark , toggleTheme } } >
{ children }
</ ThemeContext.Provider >
);
};
Using the Theme Hook
Access theme state in any component:
import { useTheme } from '@/contexts/ThemeContext' ;
function MyComponent () {
const { isDark , toggleTheme } = useTheme ();
return (
< button onClick = { toggleTheme } >
Current theme: { isDark ? 'Dark' : 'Light' }
</ button >
);
}
Color System
CSS Custom Properties
The theme uses CSS variables defined in src/index.css:
:root {
--bg-color : #080808 ;
--second-bg-color : #131313 ;
--text-color : white ;
--main-color : #00ffee ;
}
.dark {
--bg-primary : #0f172a ;
--bg-secondary : #1e293b ;
--bg-tertiary : #334155 ;
--text-primary : #f1f5f9 ;
--text-secondary : #cbd5e1 ;
--text-tertiary : #94a3b8 ;
--border-color : #475569 ;
--accent-color : #3b82f6 ;
}
Modify the default theme preference in ThemeContext.jsx:
// Change from dark to light as default
const [ isDark , setIsDark ] = useState (() => {
const saved = localStorage . getItem ( 'theme' );
return saved ? saved === 'dark' : false ; // Now defaults to light
});
Customize Dark Mode Colors
Update the dark mode color variables in src/index.css:
.dark {
--bg-primary : #1a1a2e ; /* Changed from #0f172a */
--bg-secondary : #16213e ; /* Changed from #1e293b */
--accent-color : #e94560 ; /* Changed from #3b82f6 */
}
Customize Light Mode Colors
Modify the root variables for light mode:
:root {
--bg-color : #f8f9fa ; /* Changed from #080808 */
--text-color : #212529 ; /* Changed from white */
--main-color : #0066cc ; /* Changed from #00ffee */
}
Navy Color Palette
The portfolio uses a professional navy color palette defined in tailwind.config.js:
colors : {
navy : {
50 : '#f8fafc' ,
100 : '#f1f5f9' ,
200 : '#e2e8f0' ,
300 : '#cbd5e1' ,
400 : '#94a3b8' ,
500 : '#64748b' ,
600 : '#475569' ,
700 : '#334155' ,
800 : '#1e293b' ,
900 : '#0f172a' ,
},
}
Use these navy shades consistently across components with classes like bg-navy-800, text-navy-300, or border-navy-500.
Customizing the Color Palette
Purple Theme
Green Theme
Orange Theme
// tailwind.config.js
colors : {
brand : {
50 : '#faf5ff' ,
100 : '#f3e8ff' ,
200 : '#e9d5ff' ,
300 : '#d8b4fe' ,
400 : '#c084fc' ,
500 : '#a855f7' ,
600 : '#9333ea' ,
700 : '#7e22ce' ,
800 : '#6b21a8' ,
900 : '#581c87' ,
},
}
After changing the color palette name (e.g., from navy to brand), you’ll need to update all component files that reference the old color name. Use find and replace: navy- → brand-
Theme Toggle Component
The theme toggle is implemented using an animated component:
src/components/ThemeToggle.jsx
import { AnimatedThemeToggler } from './ui/animated-theme-toggler' ;
const ThemeToggle = () => {
return < AnimatedThemeToggler /> ;
};
export default ThemeToggle ;
Customizing the Toggle Appearance
You can modify the animated theme toggler component or create your own custom toggle:
import { useTheme } from '@/contexts/ThemeContext' ;
import { Moon , Sun } from 'lucide-react' ;
const CustomThemeToggle = () => {
const { isDark , toggleTheme } = useTheme ();
return (
< button
onClick = { toggleTheme }
className = "p-2 rounded-lg bg-navy-100 dark:bg-slate-800 hover:bg-navy-200 dark:hover:bg-slate-700 transition-colors"
>
{ isDark ? < Sun size = { 20 } /> : < Moon size = { 20 } /> }
</ button >
);
};
Shadcn UI Color System
The portfolio also integrates Shadcn UI’s color system:
colors : {
background : 'hsl(var(--background))' ,
foreground : 'hsl(var(--foreground))' ,
primary : {
DEFAULT : 'hsl(var(--primary))' ,
foreground : 'hsl(var(--primary-foreground))'
},
secondary : {
DEFAULT : 'hsl(var(--secondary))' ,
foreground : 'hsl(var(--secondary-foreground))'
},
// ... more colors
}
These are defined as HSL values in your CSS for easy theming:
:root {
--background : 0 0 % 100 % ;
--foreground : 222.2 84 % 4.9 % ;
--primary : 222.2 47.4 % 11.2 % ;
}
.dark {
--background : 222.2 84 % 4.9 % ;
--foreground : 210 40 % 98 % ;
--primary : 210 40 % 98 % ;
}
Use the Shadcn themes generator to create custom color schemes that integrate seamlessly with the existing components.
Disable Theme Switching
To lock the portfolio to a single theme:
Remove or comment out the ThemeToggle component from your navigation:
// import ThemeToggle from './ThemeToggle';
// Remove from render:
// <ThemeToggle />
Modify the ThemeContext to always use one theme:
export const ThemeProvider = ({ children }) => {
const [ isDark ] = useState ( true ); // Always dark
// Remove setIsDark and toggleTheme
useEffect (() => {
document . documentElement . classList . add ( 'dark' );
}, []);
return (
< ThemeContext.Provider value = { { isDark } } >
{ children }
</ ThemeContext.Provider >
);
};
Best Practices
Consistency : Use the same color palette throughout your components
Accessibility : Ensure sufficient contrast between text and background colors
Testing : Test all components in both light and dark modes after making changes
CSS Variables : Prefer CSS custom properties for values that change between themes
Tailwind Classes : Use Tailwind’s dark: variant for theme-specific styling
Next Steps
Styling Guide Learn about Tailwind configuration and component styling
Content Updates Update personal information, projects, and services