feat: Update theme to match inou styleguide - light theme with amber accent
This commit is contained in:
parent
a6aca36522
commit
52db9d7ea6
|
|
@ -1,31 +1,394 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
/// App theme configuration
|
||||
class AppTheme {
|
||||
static const Color primaryColor = Color(0xFF6366F1); // Indigo
|
||||
static const Color secondaryColor = Color(0xFF8B5CF6); // Violet
|
||||
static const Color backgroundColor = Color(0xFF0F172A); // Slate 900
|
||||
static const Color surfaceColor = Color(0xFF1E293B); // Slate 800
|
||||
static const Color textColor = Color(0xFFF8FAFC); // Slate 50
|
||||
/// inou brand colors from styleguide
|
||||
class InouColors {
|
||||
// Primary brand colors
|
||||
static const Color accent = Color(0xFFB45309); // Amber - primary accent
|
||||
static const Color accentLight = Color(0xFFD97706); // Lighter amber for hover states
|
||||
|
||||
// Text colors
|
||||
static const Color textPrimary = Color(0xFF1C1917); // Stone 900
|
||||
static const Color textMuted = Color(0xFF78716C); // Stone 500
|
||||
static const Color textOnAccent = Color(0xFFFFFFFF); // White on accent
|
||||
|
||||
// Background colors (light theme)
|
||||
static const Color background = Color(0xFFF8F7F6); // Warm off-white
|
||||
static const Color surface = Color(0xFFFFFFFF); // Pure white for cards
|
||||
static const Color surfaceElevated = Color(0xFFFAFAF9); // Slightly elevated
|
||||
|
||||
// Background colors (dark theme)
|
||||
static const Color backgroundDark = Color(0xFF1C1917);
|
||||
static const Color surfaceDark = Color(0xFF292524);
|
||||
static const Color textPrimaryDark = Color(0xFFF5F5F4);
|
||||
static const Color textMutedDark = Color(0xFFA8A29E);
|
||||
|
||||
// Semantic colors
|
||||
static const Color success = Color(0xFF059669); // Emerald
|
||||
static const Color danger = Color(0xFFDC2626); // Red
|
||||
static const Color info = Color(0xFF3B82F6); // Blue
|
||||
static const Color warning = Color(0xFFF59E0B); // Amber
|
||||
|
||||
// Status colors
|
||||
static const Color care = Color(0xFF8B5CF6); // Violet - care status
|
||||
static const Color processing = Color(0xFF6366F1); // Indigo - processing
|
||||
}
|
||||
|
||||
/// App theme configuration following inou styleguide
|
||||
class AppTheme {
|
||||
// Expose colors for direct access
|
||||
static const Color primaryColor = InouColors.accent;
|
||||
static const Color backgroundColor = InouColors.background;
|
||||
static const Color surfaceColor = InouColors.surface;
|
||||
static const Color textColor = InouColors.textPrimary;
|
||||
|
||||
// Dark theme colors
|
||||
static const Color backgroundColorDark = InouColors.backgroundDark;
|
||||
static const Color surfaceColorDark = InouColors.surfaceDark;
|
||||
static const Color textColorDark = InouColors.textPrimaryDark;
|
||||
|
||||
/// Light theme (default, matches inou.com)
|
||||
static ThemeData get lightTheme => ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: Brightness.light,
|
||||
colorScheme: ColorScheme.light(
|
||||
primary: InouColors.accent,
|
||||
secondary: InouColors.accentLight,
|
||||
surface: InouColors.surface,
|
||||
error: InouColors.danger,
|
||||
),
|
||||
scaffoldBackgroundColor: InouColors.background,
|
||||
appBarTheme: const AppBarTheme(
|
||||
backgroundColor: InouColors.background,
|
||||
foregroundColor: InouColors.textPrimary,
|
||||
elevation: 0,
|
||||
centerTitle: false,
|
||||
titleTextStyle: TextStyle(
|
||||
color: InouColors.textPrimary,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
||||
backgroundColor: InouColors.surface,
|
||||
selectedItemColor: InouColors.accent,
|
||||
unselectedItemColor: InouColors.textMuted,
|
||||
elevation: 8,
|
||||
),
|
||||
navigationBarTheme: NavigationBarThemeData(
|
||||
backgroundColor: InouColors.surface,
|
||||
indicatorColor: InouColors.accent.withOpacity(0.15),
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return const TextStyle(
|
||||
color: InouColors.accent,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
}
|
||||
return const TextStyle(
|
||||
color: InouColors.textMuted,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
}),
|
||||
iconTheme: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return const IconThemeData(color: InouColors.accent);
|
||||
}
|
||||
return const IconThemeData(color: InouColors.textMuted);
|
||||
}),
|
||||
),
|
||||
cardTheme: CardTheme(
|
||||
color: InouColors.surface,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
side: BorderSide(color: InouColors.textMuted.withOpacity(0.1)),
|
||||
),
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: InouColors.surface,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: InouColors.textMuted.withOpacity(0.2)),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: InouColors.textMuted.withOpacity(0.2)),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: InouColors.accent, width: 2),
|
||||
),
|
||||
labelStyle: const TextStyle(color: InouColors.textMuted),
|
||||
hintStyle: TextStyle(color: InouColors.textMuted.withOpacity(0.7)),
|
||||
),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: InouColors.accent,
|
||||
foregroundColor: InouColors.textOnAccent,
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: InouColors.accent,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
textTheme: const TextTheme(
|
||||
displayLarge: TextStyle(
|
||||
fontSize: 40,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
headlineLarge: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
headlineMedium: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
headlineSmall: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
titleLarge: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
titleMedium: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
bodyLarge: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
bodyMedium: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: InouColors.textPrimary,
|
||||
),
|
||||
bodySmall: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: InouColors.textMuted,
|
||||
),
|
||||
labelLarge: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimary,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
labelSmall: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textMuted,
|
||||
letterSpacing: 1.0,
|
||||
),
|
||||
),
|
||||
dividerTheme: DividerThemeData(
|
||||
color: InouColors.textMuted.withOpacity(0.1),
|
||||
thickness: 1,
|
||||
),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
backgroundColor: InouColors.textPrimary,
|
||||
contentTextStyle: const TextStyle(color: Colors.white),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
);
|
||||
|
||||
/// Dark theme
|
||||
static ThemeData get darkTheme => ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: Brightness.dark,
|
||||
colorScheme: ColorScheme.dark(
|
||||
primary: primaryColor,
|
||||
secondary: secondaryColor,
|
||||
surface: surfaceColor,
|
||||
primary: InouColors.accent,
|
||||
secondary: InouColors.accentLight,
|
||||
surface: InouColors.surfaceDark,
|
||||
error: InouColors.danger,
|
||||
),
|
||||
scaffoldBackgroundColor: backgroundColor,
|
||||
scaffoldBackgroundColor: InouColors.backgroundDark,
|
||||
appBarTheme: const AppBarTheme(
|
||||
backgroundColor: backgroundColor,
|
||||
foregroundColor: textColor,
|
||||
backgroundColor: InouColors.backgroundDark,
|
||||
foregroundColor: InouColors.textPrimaryDark,
|
||||
elevation: 0,
|
||||
centerTitle: false,
|
||||
titleTextStyle: TextStyle(
|
||||
color: InouColors.textPrimaryDark,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
||||
backgroundColor: surfaceColor,
|
||||
selectedItemColor: primaryColor,
|
||||
unselectedItemColor: Colors.grey,
|
||||
backgroundColor: InouColors.surfaceDark,
|
||||
selectedItemColor: InouColors.accent,
|
||||
unselectedItemColor: InouColors.textMutedDark,
|
||||
elevation: 8,
|
||||
),
|
||||
navigationBarTheme: NavigationBarThemeData(
|
||||
backgroundColor: InouColors.surfaceDark,
|
||||
indicatorColor: InouColors.accent.withOpacity(0.2),
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return const TextStyle(
|
||||
color: InouColors.accent,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
}
|
||||
return const TextStyle(
|
||||
color: InouColors.textMutedDark,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
}),
|
||||
iconTheme: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return const IconThemeData(color: InouColors.accent);
|
||||
}
|
||||
return const IconThemeData(color: InouColors.textMutedDark);
|
||||
}),
|
||||
),
|
||||
cardTheme: CardTheme(
|
||||
color: InouColors.surfaceDark,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
side: BorderSide(color: InouColors.textMutedDark.withOpacity(0.15)),
|
||||
),
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: InouColors.surfaceDark,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: InouColors.textMutedDark.withOpacity(0.3)),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: InouColors.textMutedDark.withOpacity(0.3)),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: const BorderSide(color: InouColors.accent, width: 2),
|
||||
),
|
||||
labelStyle: const TextStyle(color: InouColors.textMutedDark),
|
||||
hintStyle: TextStyle(color: InouColors.textMutedDark.withOpacity(0.7)),
|
||||
),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: InouColors.accent,
|
||||
foregroundColor: InouColors.textOnAccent,
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: InouColors.accent,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
textTheme: const TextTheme(
|
||||
displayLarge: TextStyle(
|
||||
fontSize: 40,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
headlineLarge: TextStyle(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
headlineMedium: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
headlineSmall: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
titleLarge: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
titleMedium: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
bodyLarge: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
bodyMedium: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: InouColors.textPrimaryDark,
|
||||
),
|
||||
bodySmall: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: InouColors.textMutedDark,
|
||||
),
|
||||
labelLarge: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textPrimaryDark,
|
||||
letterSpacing: 0.5,
|
||||
),
|
||||
labelSmall: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: InouColors.textMutedDark,
|
||||
letterSpacing: 1.0,
|
||||
),
|
||||
),
|
||||
dividerTheme: DividerThemeData(
|
||||
color: InouColors.textMutedDark.withOpacity(0.15),
|
||||
thickness: 1,
|
||||
),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
backgroundColor: InouColors.surfaceDark,
|
||||
contentTextStyle: const TextStyle(color: InouColors.textPrimaryDark),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ class _InouAppState extends State<InouApp> {
|
|||
return MaterialApp(
|
||||
navigatorKey: InouApp.navigatorKey,
|
||||
title: AppConfig.appName,
|
||||
theme: AppTheme.darkTheme,
|
||||
theme: AppTheme.lightTheme,
|
||||
darkTheme: AppTheme.darkTheme,
|
||||
themeMode: ThemeMode.light, // Use light theme to match inou.com
|
||||
debugShowCheckedModeBanner: false,
|
||||
// TODO: Re-enable AuthGate for production
|
||||
// home: const AuthGate(
|
||||
|
|
|
|||
Loading…
Reference in New Issue