fix light theme

This commit is contained in:
Fabian Freund
2026-03-18 07:52:13 +01:00
parent 978606f4ae
commit 5d3f394f7b
4 changed files with 254 additions and 178 deletions
+97 -15
View File
@@ -22,19 +22,25 @@ import 'package:flutter/material.dart';
@immutable @immutable
class AppColors extends ThemeExtension<AppColors> { class AppColors extends ThemeExtension<AppColors> {
const AppColors._({ const AppColors._({
this.seedColor = const Color(0xFF167C80), required this.seedColor,
this.privateTabPurple = const Color(0xFF8000D7), required this.privateTabPurple,
this.privateTabBackground = const Color(0xFF25003E), required this.privateTabBackground,
this.privateTabForeground = const Color(0xFFFFFFFF), required this.privateTabForeground,
this.privateSelectionOverlay = const Color(0x648000D7), required this.privateSelectionOverlay,
this.isolatedTabTeal = const Color(0xFF00897B), required this.isolatedTabTeal,
this.isolatedTabBackground = const Color(0xFF003D36), required this.isolatedTabBackground,
this.isolatedTabForeground = const Color(0xFFFFFFFF), required this.isolatedTabForeground,
this.isolatedSelectionOverlay = const Color(0x6400897B), required this.isolatedSelectionOverlay,
this.torPurple = const Color(0xFF7D4698), required this.torPurple,
this.torActiveGreen = const Color(0xFF68B030), required this.torActiveGreen,
this.torBackgroundGrey = const Color(0xFF333A41), required this.torBackgroundGrey,
this.warningAmber = const Color(0xFFFFA000), required this.warningAmber,
required this.auraPurple,
required this.auraGold,
required this.auraShadow,
required this.auraShadowHighlight,
required this.auraTint,
required this.brandLink,
}); });
final Color seedColor; final Color seedColor;
@@ -50,9 +56,63 @@ class AppColors extends ThemeExtension<AppColors> {
final Color torActiveGreen; final Color torActiveGreen;
final Color torBackgroundGrey; final Color torBackgroundGrey;
final Color warningAmber; final Color warningAmber;
final Color auraPurple;
final Color auraGold;
final Color auraShadow;
final Color auraShadowHighlight;
final Color auraTint;
final Color brandLink;
static const light = AppColors._(); /// Brand colors derived from the logo (constant across themes).
static const dark = AppColors._(); static const brandPurple = Color(0xFF9C83F8);
static const brandYellow = Color(0xFFFBDC6B);
static const brandGrey = Color(0xFFA7A7A7);
static const light = AppColors._(
seedColor: Color(0xFF167C80),
privateTabPurple: Color(0xFF8000D7),
privateTabBackground: Color(0xFFF3E5F5),
privateTabForeground: Color(0xFF4A0072),
privateSelectionOverlay: Color(0x648000D7),
isolatedTabTeal: Color(0xFF00897B),
isolatedTabBackground: Color(0xFFE0F2F1),
isolatedTabForeground: Color(0xFF004D40),
isolatedSelectionOverlay: Color(0x6400897B),
torPurple: Color(0xFF7D4698),
torActiveGreen: Color(0xFF68B030),
torBackgroundGrey: Color(0xFFECEFF1),
warningAmber: Color(0xFFFFA000),
// Aura: brand colors lightened toward white
auraPurple: Color(0xFFE0D6FC),
auraGold: Color(0xFFFDF1D6),
auraShadow: Color(0xFFEDEDF0),
auraShadowHighlight: Color(0xFFE2E2E7),
auraTint: Color(0xFFFFFFFF),
brandLink: Color(0xFF7A5AF0),
);
static const dark = AppColors._(
seedColor: Color(0xFF167C80),
privateTabPurple: Color(0xFF8000D7),
privateTabBackground: Color(0xFF25003E),
privateTabForeground: Color(0xFFFFFFFF),
privateSelectionOverlay: Color(0x648000D7),
isolatedTabTeal: Color(0xFF00897B),
isolatedTabBackground: Color(0xFF003D36),
isolatedTabForeground: Color(0xFFFFFFFF),
isolatedSelectionOverlay: Color(0x6400897B),
torPurple: Color(0xFF7D4698),
torActiveGreen: Color(0xFF68B030),
torBackgroundGrey: Color(0xFF333A41),
warningAmber: Color(0xFFFFA000),
// Aura: brand colors darkened toward black
auraPurple: Color(0xFF2C2543),
auraGold: Color(0xFF3C3827),
auraShadow: Color(0xFF222224),
auraShadowHighlight: Color(0xFF2D2D31),
auraTint: Color(0xFF000000),
brandLink: Color(0xFFFBDC6B),
);
@override @override
AppColors copyWith({ AppColors copyWith({
@@ -69,6 +129,12 @@ class AppColors extends ThemeExtension<AppColors> {
Color? torActiveGreen, Color? torActiveGreen,
Color? torBackgroundGrey, Color? torBackgroundGrey,
Color? warningAmber, Color? warningAmber,
Color? auraPurple,
Color? auraGold,
Color? auraShadow,
Color? auraShadowHighlight,
Color? auraTint,
Color? brandLink,
}) { }) {
return AppColors._( return AppColors._(
seedColor: seedColor ?? this.seedColor, seedColor: seedColor ?? this.seedColor,
@@ -88,6 +154,12 @@ class AppColors extends ThemeExtension<AppColors> {
torActiveGreen: torActiveGreen ?? this.torActiveGreen, torActiveGreen: torActiveGreen ?? this.torActiveGreen,
torBackgroundGrey: torBackgroundGrey ?? this.torBackgroundGrey, torBackgroundGrey: torBackgroundGrey ?? this.torBackgroundGrey,
warningAmber: warningAmber ?? this.warningAmber, warningAmber: warningAmber ?? this.warningAmber,
auraPurple: auraPurple ?? this.auraPurple,
auraGold: auraGold ?? this.auraGold,
auraShadow: auraShadow ?? this.auraShadow,
auraShadowHighlight: auraShadowHighlight ?? this.auraShadowHighlight,
auraTint: auraTint ?? this.auraTint,
brandLink: brandLink ?? this.brandLink,
); );
} }
@@ -143,6 +215,16 @@ class AppColors extends ThemeExtension<AppColors> {
t, t,
)!, )!,
warningAmber: Color.lerp(warningAmber, other.warningAmber, t)!, warningAmber: Color.lerp(warningAmber, other.warningAmber, t)!,
auraPurple: Color.lerp(auraPurple, other.auraPurple, t)!,
auraGold: Color.lerp(auraGold, other.auraGold, t)!,
auraShadow: Color.lerp(auraShadow, other.auraShadow, t)!,
auraShadowHighlight: Color.lerp(
auraShadowHighlight,
other.auraShadowHighlight,
t,
)!,
auraTint: Color.lerp(auraTint, other.auraTint, t)!,
brandLink: Color.lerp(brandLink, other.brandLink, t)!,
); );
} }
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart'; import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/core/routing/routes.dart'; import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_list.dart'; import 'package:weblibre/features/geckoview/domain/providers/tab_list.dart';
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart'; import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
@@ -129,7 +130,7 @@ class BrowserHome extends ConsumerWidget {
borderRadius: BorderRadius.circular(28), borderRadius: BorderRadius.circular(28),
border: Border.all( border: Border.all(
color: Color.alphaBlend( color: Color.alphaBlend(
BrowserPage.brandGrey.withValues(alpha: 0.18), AppColors.brandGrey.withValues(alpha: 0.18),
colorScheme.outlineVariant, colorScheme.outlineVariant,
), ),
), ),
@@ -21,6 +21,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:weblibre/core/design/app_colors.dart';
import 'package:weblibre/features/onboarding/domain/entities/onboarding_mode.dart'; import 'package:weblibre/features/onboarding/domain/entities/onboarding_mode.dart';
import 'package:weblibre/features/onboarding/domain/providers.dart'; import 'package:weblibre/features/onboarding/domain/providers.dart';
import 'package:weblibre/presentation/widgets/browser_page.dart'; import 'package:weblibre/presentation/widgets/browser_page.dart';
@@ -130,9 +131,9 @@ class _UpdateNotice extends StatelessWidget {
children: [ children: [
Row( Row(
children: [ children: [
const Icon( Icon(
Icons.auto_awesome, Icons.auto_awesome,
color: BrowserPage.brandYellow, color: AppColors.of(context).brandLink,
size: 20, size: 20,
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
@@ -244,7 +245,7 @@ class _ModeOption extends StatelessWidget {
Icon( Icon(
icon, icon,
color: selected color: selected
? BrowserPage.brandYellow ? AppColors.of(context).brandLink
: colorScheme.onSurfaceVariant, : colorScheme.onSurfaceVariant,
size: 28, size: 28,
), ),
@@ -320,9 +321,9 @@ class _EulaCheckbox extends StatelessWidget {
child: Text( child: Text(
'EULA', 'EULA',
style: theme.textTheme.bodySmall?.copyWith( style: theme.textTheme.bodySmall?.copyWith(
color: BrowserPage.brandYellow, color: AppColors.of(context).brandLink,
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
decorationColor: BrowserPage.brandYellow, decorationColor: AppColors.of(context).brandLink,
), ),
), ),
), ),
@@ -341,9 +342,9 @@ class _EulaCheckbox extends StatelessWidget {
child: Text( child: Text(
'Privacy Policy', 'Privacy Policy',
style: theme.textTheme.bodySmall?.copyWith( style: theme.textTheme.bodySmall?.copyWith(
color: BrowserPage.brandYellow, color: AppColors.of(context).brandLink,
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
decorationColor: BrowserPage.brandYellow, decorationColor: AppColors.of(context).brandLink,
), ),
), ),
), ),
+14 -22
View File
@@ -4,6 +4,7 @@ import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:weblibre/core/design/app_colors.dart';
class BrowserPage extends ConsumerWidget { class BrowserPage extends ConsumerWidget {
final double bottomViewportInset; final double bottomViewportInset;
@@ -11,20 +12,11 @@ class BrowserPage extends ConsumerWidget {
const BrowserPage({super.key, this.bottomViewportInset = 0, required this.child}); const BrowserPage({super.key, this.bottomViewportInset = 0, required this.child});
static const brandPurple = Color(0xFF9C83F8);
static const brandYellow = Color(0xFFFBDC6B);
static const brandGrey = Color(0xFFA7A7A7);
static const auraPurple = Color(0xFF2C2543);
static const auraGold = Color(0xFF3C3827);
static const auraShadow = Color(0xFF222224);
static const auraShadowHighlight = Color(0xFF2D2D31);
static const auraTint = Color(0xFF000000);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context); final theme = Theme.of(context);
final colorScheme = theme.colorScheme; final colorScheme = theme.colorScheme;
final appColors = AppColors.of(context);
return DecoratedBox( return DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -33,15 +25,15 @@ class BrowserPage extends ConsumerWidget {
end: Alignment.bottomRight, end: Alignment.bottomRight,
colors: [ colors: [
Color.alphaBlend( Color.alphaBlend(
auraPurple.withValues(alpha: 0.38), appColors.auraPurple.withValues(alpha: 0.38),
colorScheme.surfaceContainerLowest, colorScheme.surfaceContainerLowest,
), ),
Color.alphaBlend( Color.alphaBlend(
auraShadow.withValues(alpha: 0.72), appColors.auraShadow.withValues(alpha: 0.72),
colorScheme.surface, colorScheme.surface,
), ),
Color.alphaBlend( Color.alphaBlend(
auraGold.withValues(alpha: 0.34), appColors.auraGold.withValues(alpha: 0.34),
colorScheme.surfaceContainerHigh, colorScheme.surfaceContainerHigh,
), ),
], ],
@@ -50,23 +42,23 @@ class BrowserPage extends ConsumerWidget {
child: Stack( child: Stack(
fit: StackFit.expand, fit: StackFit.expand,
children: [ children: [
const Positioned( Positioned(
top: -70, top: -70,
left: -120, left: -120,
child: _BackdropOrb(width: 400, height: 400, color: auraPurple), child: _BackdropOrb(width: 400, height: 400, color: appColors.auraPurple),
), ),
const Positioned( Positioned(
top: 220, top: 220,
right: -150, right: -150,
child: _BackdropOrb(width: 340, height: 340, color: auraGold), child: _BackdropOrb(width: 340, height: 340, color: appColors.auraGold),
), ),
const Positioned( Positioned(
bottom: 18, bottom: 18,
left: -8, left: -8,
child: _BackdropOrb( child: _BackdropOrb(
width: 320, width: 320,
height: 320, height: 320,
color: auraShadowHighlight, color: appColors.auraShadowHighlight,
), ),
), ),
Positioned.fill( Positioned.fill(
@@ -74,7 +66,7 @@ class BrowserPage extends ConsumerWidget {
child: ClipRect( child: ClipRect(
child: BackdropFilter( child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 72, sigmaY: 72), filter: ImageFilter.blur(sigmaX: 72, sigmaY: 72),
child: ColoredBox(color: auraTint.withValues(alpha: 0.12)), child: ColoredBox(color: appColors.auraTint.withValues(alpha: 0.12)),
), ),
), ),
), ),
@@ -146,11 +138,11 @@ class BrandHeader extends StatelessWidget {
end: Alignment.bottomRight, end: Alignment.bottomRight,
colors: [ colors: [
Color.alphaBlend( Color.alphaBlend(
BrowserPage.brandPurple.withValues(alpha: 0.18), AppColors.brandPurple.withValues(alpha: 0.18),
colorScheme.surfaceContainerHighest, colorScheme.surfaceContainerHighest,
), ),
Color.alphaBlend( Color.alphaBlend(
BrowserPage.brandYellow.withValues(alpha: 0.12), AppColors.brandYellow.withValues(alpha: 0.12),
colorScheme.surfaceContainer, colorScheme.surfaceContainer,
), ),
], ],