The FocusQuest theme system provides a comprehensive, ADHD-friendly color palette and theme configuration for both light and dark modes. The theme is designed with principles that reduce visual stress and cognitive load.
- No pure black (
#000000) or pure white (#FFFFFF) - Soft pastels and muted tones
- Low contrast for reduced visual stress
- Rounded surfaces (12-16px border radius)
- Soft shadows only (low elevation)
- No harsh borders or high-contrast edges
- Calm greens and warm neutrals
- Muted tones throughout
- Consistent color language across light and dark themes
lib/core/theme/
├── app_colors.dart # Color palette definitions
├── app_theme.dart # ThemeData configurations
└── theme.md # This documentation
lib/providers/
└── theme_provider.dart # Riverpod state management & persistence
| Purpose | Color | Hex Code |
|---|---|---|
| Background | Warm cream / soft beige | #F5F1E8 |
| Primary | Muted green | #7A9E7E |
| Secondary | Soft teal | #6B9A9A |
| Surface | Off-white | #FAF8F3 |
| Text Primary | Charcoal | #2C2C2C |
| Text Secondary | Muted gray | #6B6B6B |
| Accent | Soft yellow | #E8D5A3 |
| Success | Calm green | #7A9E7E |
| Warning | Soft orange | #D4A574 |
| Error | Muted red | #C97D7D |
| Purpose | Color | Hex Code |
|---|---|---|
| Background | Deep olive / warm dark | #1E2A1F |
| Primary | Muted mint | #7A9E7E |
| Secondary | Soft teal | #6B9A9A |
| Surface | Dark gray-green | #2A352B |
| Text Primary | Warm off-white | #E8E5DF |
| Text Secondary | Soft gray | #9A9A9A |
| Accent | Desaturated yellow | #B8A67A |
| Success | Calm green | #7A9E7E |
| Warning | Soft orange | #D4A574 |
| Error | Muted red | #C97D7D |
The theme is automatically applied through the ThemeProvider in main.dart:
import 'package:focus_quest/core/theme/app_theme.dart';
import 'package:focus_quest/providers/theme_provider.dart';
// In your widget:
final themeMode = ref.watch(themeModeProvider);
MaterialApp(
theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
themeMode: themeMode,
// ...
)// In a widget:
final colorScheme = Theme.of(context).colorScheme;
// Use colors:
Container(
color: colorScheme.primary,
child: Text(
'Hello',
style: TextStyle(color: colorScheme.onPrimary),
),
)import 'package:focus_quest/core/theme/app_colors.dart';
Container(
color: AppColors.lightPrimary,
// or
color: AppColors.darkPrimary,
)import 'package:focus_quest/providers/theme_provider.dart';
// Toggle between light and dark
ref.read(themeProvider.notifier).toggleTheme();
// Set specific theme
ref.read(themeProvider.notifier).setTheme(AppThemeMode.light);
ref.read(themeProvider.notifier).setTheme(AppThemeMode.dark);
ref.read(themeProvider.notifier).setTheme(AppThemeMode.system);- Default:
12.0px- Used for buttons, inputs, and general UI elements - Large:
16.0px- Used for cards and containers - Small:
8.0px- Used for chips and small elements
All shadows use low opacity (0.05-0.3) to maintain the soft, ADHD-friendly aesthetic:
- Cards:
elevation: 2withopacity: 0.05 - Buttons:
elevation: 2withopacity: 0.1 - Dialogs:
elevation: 8withopacity: 0.1
The theme includes a comprehensive text theme with:
- Display styles (32px, 28px, 24px)
- Headline styles (20px)
- Title styles (18px, 16px)
- Body styles (16px, 14px, 12px)
- Label styles (14px)
All text colors respect the theme's contrast requirements.
The theme system uses Riverpod for state management:
// Theme state provider
final themeProvider = StateNotifierProvider<ThemeNotifier, ThemeState>(...);
// Theme mode provider (convenience)
final themeModeProvider = Provider<ThemeMode>(...);Theme preferences are persisted using Sembast (via PreferenceStorageService):
- Theme mode is saved automatically when changed
- Theme preference survives app restarts
- Storage key:
theme_mode
The app supports three theme modes:
AppThemeMode.light- Always light themeAppThemeMode.dark- Always dark themeAppThemeMode.system- Follows system preference (default)
- Add color constants to
app_colors.dart:
static const Color lightNewColor = Color(0xFF...);
static const Color darkNewColor = Color(0xFF...);-
Update
ColorSchemeinapp_colors.dartif needed -
Use the color in your widgets or add to
app_theme.dartcomponent themes
Edit app_theme.dart to customize component themes:
// Example: Customize button theme
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
// Your customizations
),
),- Toggle Theme: Use
themeProvider.notifier.toggleTheme() - Restart App: Verify theme persists after restart
- System Theme: Set to system mode and verify it follows device settings
- Theme toggles correctly between light and dark
- Theme persists after app restart
- System theme follows device preference
- All UI components respect theme colors
- No pure black or white colors appear
- Borders and shadows are soft and low-contrast
- Text is readable in both themes
- Always use theme colors - Don't hardcode colors, use
Theme.of(context).colorScheme - Respect theme mode - Don't force light/dark, use the provider
- Test both themes - Ensure UI works in both light and dark modes
- Maintain consistency - Use the defined color palette, don't introduce new colors without updating the palette
- Follow border radius - Use
AppTheme.borderRadiusconstants for consistency
The theme system follows the project's local-first architecture:
- State Management: Riverpod (compile-time safe)
- Persistence: Sembast (local-first, offline-capable)
- Separation of Concerns: Colors, Theme, and Provider are separate files
This ensures the theme system is:
- ✅ Testable
- ✅ Maintainable
- ✅ Consistent with project architecture
- ✅ Offline-capable