- Updated database connection to support Turso auth token - Added vercel.json with bun build configuration - Updated environment schema for production deployment - Added new features and components for production readiness
8.5 KiB
Dark Mode Implementation Guide
Overview
BeenVoice implements a media query-based dark mode system that automatically adapts to the user's system preferences. This approach provides a seamless experience without requiring manual theme switching controls.
Implementation Approach
Media Query-Based vs Class-Based
We chose media query-based dark mode (@media (prefers-color-scheme: dark)) over class-based dark mode for the following reasons:
- Automatic System Integration: Respects user's OS/browser theme preference
- No JavaScript Required: Pure CSS solution with better performance
- Better Accessibility: Follows system accessibility settings
- Seamless Experience: No flash of incorrect theme on page load
- Reduced Complexity: No need for theme toggle components or state management
Configuration Changes
1. Tailwind CSS Configuration
File: tailwind.config.ts
export default {
darkMode: "media", // Changed from "class" to "media"
// ... rest of config
} satisfies Config;
2. Global CSS Updates
File: src/styles/globals.css
Key changes made:
- Replaced
.dark { }class selector with@media (prefers-color-scheme: dark) { :root { } } - Maintained all existing CSS custom properties
- Updated dark mode color definitions to use media queries
@media (prefers-color-scheme: dark) {
:root {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
/* ... all other dark mode variables */
}
}
Component Updates
Core Layout Components
1. Root Layout (src/app/layout.tsx)
- Updated background gradients with dark mode variants
- Improved layering structure for background effects
- Added proper z-index management
2. Landing Page (src/app/page.tsx)
- Comprehensive dark mode classes for all sections
- Updated text colors, backgrounds, and hover states
- Maintained brand consistency with green color scheme
3. Authentication Pages
- Sign In Page (
src/app/auth/signin/page.tsx) - Register Page (
src/app/auth/register/page.tsx)
Both pages updated with:
- Dark background gradients
- Card component dark backgrounds
- Input field icon colors
- Text color variations
- Link hover states
Navigation Components
1. Navbar (src/components/Navbar.tsx)
- Glass morphism effect with dark background support
- Button variant adaptations
- Text color adjustments for user information
2. Sidebar (src/components/Sidebar.tsx)
- Dark background with transparency
- Navigation link states (active/hover)
- Border color adaptations
- Icon and text color updates
3. Mobile Sidebar (src/components/SidebarTrigger.tsx)
- Sheet component dark styling
- Navigation link consistency with desktop sidebar
- Border and background adaptations
Dashboard Components
1. Dashboard Page (src/app/dashboard/page.tsx)
- Welcome text color adjustments
- Maintained gradient text effects
2. Universal Table (src/components/ui/universal-table.tsx)
- Comprehensive table styling updates
- Header background and text colors
- Cell content color adaptations
- Status badge color schemes
- Pagination control styling
- Grid view card backgrounds
Color System
Text Colors
- Primary Text:
text-gray-900 dark:text-white - Secondary Text:
text-gray-700 dark:text-gray-300 - Muted Text:
text-gray-500 dark:text-gray-400 - Icon Colors:
text-gray-400 dark:text-gray-500
Background Colors
- Card Backgrounds:
dark:bg-gray-800 - Hover States:
hover:bg-gray-100 dark:hover:bg-gray-800 - Border Colors:
border-gray-200 dark:border-gray-700 - Glass Effects:
bg-white/60 dark:bg-gray-900/60
Brand Colors
Maintained consistent green brand colors with dark mode adaptations:
- Primary Green:
text-green-600 dark:text-green-400 - Emerald Accents:
bg-emerald-100 dark:bg-emerald-900/30
Testing the Implementation
Manual Testing
-
System Theme Toggle:
- Change your OS dark/light mode setting
- Verify automatic theme switching
- Check for smooth transitions
-
Page Coverage:
- Landing page
- Authentication pages (sign in/register)
- Dashboard and navigation
- All table views and components
-
Component Testing:
- Form elements (inputs, buttons, selects)
- Cards and containers
- Navigation states (hover, active)
- Text readability in both modes
Browser Developer Tools
-
Media Query Testing:
/* In DevTools Console */ document.documentElement.style.colorScheme = 'dark'; document.documentElement.style.colorScheme = 'light'; -
Emulation:
- Chrome DevTools > Rendering > Emulate CSS prefers-color-scheme
- Firefox DevTools > Settings > Dark theme simulation
Test Component
A comprehensive test component is available at src/components/dark-mode-test.tsx that displays:
- Color variations
- Button states
- Form elements
- Status indicators
- Background patterns
- Icon colors
Best Practices for Future Development
1. Color Class Patterns
Always pair light mode colors with dark mode variants:
// ✅ Good
<div className="text-gray-900 dark:text-white bg-white dark:bg-gray-800">
// ❌ Avoid
<div className="text-gray-900 bg-white">
2. Common Patterns
Text Colors:
// Primary text
className="text-gray-900 dark:text-white"
// Secondary text
className="text-gray-700 dark:text-gray-300"
// Muted text
className="text-gray-500 dark:text-gray-400"
Backgrounds:
// Card backgrounds
className="bg-white dark:bg-gray-800"
// Hover states
className="hover:bg-gray-100 dark:hover:bg-gray-800"
// Borders
className="border-gray-200 dark:border-gray-700"
Interactive Elements:
// Links
className="text-green-600 hover:text-green-700 dark:text-green-400 dark:hover:text-green-300"
// Active states
className="bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
3. Component Development Guidelines
- Always test both modes during development
- Use semantic color tokens from the design system when possible
- Maintain sufficient contrast for accessibility
- Consider glass morphism effects with appropriate alpha values
- Test with real content to ensure readability
4. shadcn/ui Components
Most shadcn/ui components already include dark mode support:
- Button variants adapt automatically
- Input fields use CSS custom properties
- Card components respond to theme changes
For custom components, follow the established patterns.
Troubleshooting
Common Issues
-
Colors Not Switching:
- Verify
darkMode: "media"intailwind.config.ts - Check CSS custom properties are properly defined
- Ensure no conflicting class-based dark mode styles
- Verify
-
Flash of Incorrect Theme:
- Should not occur with media query approach
- If present, check for JavaScript theme switching code
-
Incomplete Styling:
- Search for hardcoded colors:
text-gray-XXXwithoutdark:variants - Use component test page to verify all elements
- Search for hardcoded colors:
-
Performance Issues:
- Media query approach should have no performance impact
- CSS variables resolve efficiently
Debugging Tools
-
CSS Custom Properties Inspector:
// In DevTools Console getComputedStyle(document.documentElement).getPropertyValue('--background') -
Media Query Detection:
// Check current preference window.matchMedia('(prefers-color-scheme: dark)').matches
Browser Support
The media query-based approach is supported in:
- Chrome 76+
- Firefox 67+
- Safari 12.1+
- Edge 79+
For older browsers, the light theme serves as a fallback.
Maintenance
Regular Checks
- New Component Integration: Ensure new components follow dark mode patterns
- Third-party Components: Verify external components adapt to theme
- Asset Updates: Check images/icons work in both modes
- Performance Monitoring: Ensure no CSS bloat from unused dark mode classes
Updates and Migration
If future requirements need class-based dark mode:
- Update
tailwind.config.tstodarkMode: "class" - Add theme toggle component
- Implement theme persistence
- Update CSS to use
.darkselector instead of media queries
Conclusion
The media query-based dark mode implementation provides a robust, performant, and user-friendly theming solution that automatically adapts to user preferences while maintaining design consistency and accessibility standards.