import 'package:flutter/material.dart'; @immutable class AppPalette extends ThemeExtension { static const Color darkDefaultThemeSeedColor = Colors.amber; static const Color lightDefaultThemeSeedColor = Colors.blue; static const List defaultCategoryColors = [ Colors.amber, Colors.blue, Colors.green, Colors.purple, Colors.red, Colors.teal, Colors.orange, Colors.grey, ]; static const List themeSeedColors = [ Colors.blue, Colors.teal, Colors.green, Colors.pink, Colors.purple, Colors.orange, ]; const AppPalette({ required this.backdropGradient, required this.drawerBackground, required this.cardBackground, required this.categoryColors, required this.surfaceElevated, required this.border, required this.borderMuted, required this.accent, required this.textPrimary, required this.textSecondary, required this.textOnSurfaceDark, required this.textMuted, required this.textDisabled, required this.textHint, required this.fill, required this.hover, required this.shadowSoft, required this.shadowDim, required this.destructiveAccent, required this.textOnAccent, required this.overlay, required this.transparent, required this.dragTargetBorder, required this.syncPreparing, required this.syncEncrypting, required this.syncUploading, required this.syncWaiting, required this.syncDecrypting, required this.success, }); final Gradient backdropGradient; final Color drawerBackground; final Color cardBackground; final List categoryColors; final Color surfaceElevated; final Color border; final Color borderMuted; final Color accent; final Color textPrimary; final Color textSecondary; final Color textOnSurfaceDark; final Color textMuted; final Color textDisabled; final Color textHint; final Color fill; final Color hover; final Color shadowSoft; final Color shadowDim; final Color destructiveAccent; final Color textOnAccent; final Color overlay; final Color transparent; final Color dragTargetBorder; final Color syncPreparing; final Color syncEncrypting; final Color syncUploading; final Color syncWaiting; final Color syncDecrypting; final Color success; @override AppPalette copyWith({ Gradient? backdropGradient, Color? drawerBackground, Color? cardBackground, List? categoryColors, Color? surfaceElevated, Color? border, Color? borderMuted, Color? accent, Color? textPrimary, Color? textSecondary, Color? textOnSurfaceDark, Color? textMuted, Color? textDisabled, Color? textHint, Color? fill, Color? hover, Color? shadowSoft, Color? shadowDim, Color? destructiveAccent, Color? textOnAccent, Color? overlay, Color? transparent, Color? dragTargetBorder, Color? syncPreparing, Color? syncEncrypting, Color? syncUploading, Color? syncWaiting, Color? syncDecrypting, Color? success, }) { return AppPalette( backdropGradient: backdropGradient ?? this.backdropGradient, drawerBackground: drawerBackground ?? this.drawerBackground, cardBackground: cardBackground ?? this.cardBackground, categoryColors: categoryColors ?? this.categoryColors, surfaceElevated: surfaceElevated ?? this.surfaceElevated, border: border ?? this.border, borderMuted: borderMuted ?? this.borderMuted, accent: accent ?? this.accent, textPrimary: textPrimary ?? this.textPrimary, textSecondary: textSecondary ?? this.textSecondary, textOnSurfaceDark: textOnSurfaceDark ?? this.textOnSurfaceDark, textMuted: textMuted ?? this.textMuted, textDisabled: textDisabled ?? this.textDisabled, textHint: textHint ?? this.textHint, fill: fill ?? this.fill, hover: hover ?? this.hover, shadowSoft: shadowSoft ?? this.shadowSoft, shadowDim: shadowDim ?? this.shadowDim, destructiveAccent: destructiveAccent ?? this.destructiveAccent, textOnAccent: textOnAccent ?? this.textOnAccent, overlay: overlay ?? this.overlay, transparent: transparent ?? this.transparent, dragTargetBorder: dragTargetBorder ?? this.dragTargetBorder, syncPreparing: syncPreparing ?? this.syncPreparing, syncEncrypting: syncEncrypting ?? this.syncEncrypting, syncUploading: syncUploading ?? this.syncUploading, syncWaiting: syncWaiting ?? this.syncWaiting, syncDecrypting: syncDecrypting ?? this.syncDecrypting, success: success ?? this.success, ); } @override AppPalette lerp(ThemeExtension? other, double t) { if (other is! AppPalette) return this; return AppPalette( backdropGradient: LinearGradient.lerp( backdropGradient as LinearGradient, other.backdropGradient as LinearGradient, t, ) ?? backdropGradient, drawerBackground: Color.lerp(drawerBackground, other.drawerBackground, t) ?? drawerBackground, cardBackground: Color.lerp(cardBackground, other.cardBackground, t) ?? cardBackground, categoryColors: t < 0.5 ? categoryColors : other.categoryColors, surfaceElevated: Color.lerp(surfaceElevated, other.surfaceElevated, t) ?? surfaceElevated, border: Color.lerp(border, other.border, t) ?? border, borderMuted: Color.lerp(borderMuted, other.borderMuted, t) ?? borderMuted, accent: Color.lerp(accent, other.accent, t) ?? accent, textPrimary: Color.lerp(textPrimary, other.textPrimary, t) ?? textPrimary, textSecondary: Color.lerp(textSecondary, other.textSecondary, t) ?? textSecondary, textOnSurfaceDark: Color.lerp(textOnSurfaceDark, other.textOnSurfaceDark, t) ?? textOnSurfaceDark, textMuted: Color.lerp(textMuted, other.textMuted, t) ?? textMuted, textDisabled: Color.lerp(textDisabled, other.textDisabled, t) ?? textDisabled, textHint: Color.lerp(textHint, other.textHint, t) ?? textHint, fill: Color.lerp(fill, other.fill, t) ?? fill, hover: Color.lerp(hover, other.hover, t) ?? hover, shadowSoft: Color.lerp(shadowSoft, other.shadowSoft, t) ?? shadowSoft, shadowDim: Color.lerp(shadowDim, other.shadowDim, t) ?? shadowDim, destructiveAccent: Color.lerp(destructiveAccent, other.destructiveAccent, t) ?? destructiveAccent, textOnAccent: Color.lerp(textOnAccent, other.textOnAccent, t) ?? textOnAccent, overlay: Color.lerp(overlay, other.overlay, t) ?? overlay, transparent: Color.lerp(transparent, other.transparent, t) ?? transparent, dragTargetBorder: Color.lerp(dragTargetBorder, other.dragTargetBorder, t) ?? dragTargetBorder, syncPreparing: Color.lerp(syncPreparing, other.syncPreparing, t) ?? syncPreparing, syncEncrypting: Color.lerp(syncEncrypting, other.syncEncrypting, t) ?? syncEncrypting, syncUploading: Color.lerp(syncUploading, other.syncUploading, t) ?? syncUploading, syncWaiting: Color.lerp(syncWaiting, other.syncWaiting, t) ?? syncWaiting, syncDecrypting: Color.lerp(syncDecrypting, other.syncDecrypting, t) ?? syncDecrypting, success: Color.lerp(success, other.success, t) ?? success, ); } static AppPalette fromBrightness(Brightness brightness, {Color? seedColor}) { final bool isLight = brightness == Brightness.light; return AppPalette( backdropGradient: isLight ? const LinearGradient( colors: [ Color(0xFFFFFFFF), Color(0xFFF2F4F6), Color(0xFFECEFF1), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ) : const LinearGradient( colors: [ Color(0xFF191A1D), Color(0xFF222326), Color(0xFF101114), ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), drawerBackground: isLight ? const Color(0xFFF7F9FA) : const Color.fromARGB(255, 30, 31, 35), cardBackground: isLight ? const Color(0xFFFFFFFF) : const Color.fromRGBO(24, 25, 26, 1), categoryColors: defaultCategoryColors, surfaceElevated: isLight ? const Color(0xFFF0F2F4) : const Color(0xFF303134), border: isLight ? const Color.fromRGBO(15, 23, 32, 0.06) : const Color.fromRGBO(255, 255, 255, 0.12), borderMuted: isLight ? const Color.fromRGBO(15, 23, 32, 0.03) : const Color.fromRGBO(255, 255, 255, 0.08), accent: seedColor ?? (isLight ? AppPalette.lightDefaultThemeSeedColor : AppPalette.darkDefaultThemeSeedColor), textPrimary: isLight ? const Color(0xFF0F1720) : Colors.white, textSecondary: isLight ? const Color(0xFF374151) : Colors.white70, textOnSurfaceDark: isLight ? Colors.black87 : Colors.black87, textMuted: isLight ? const Color(0xFF6B7280) : Colors.white54, textDisabled: isLight ? const Color(0xFFBDBDBD) : Colors.white24, textHint: isLight ? const Color.fromRGBO(15, 23, 32, 0.30) : const Color.fromRGBO(255, 255, 255, 0.30), fill: isLight ? const Color.fromRGBO(15, 23, 32, 0.02) : const Color.fromRGBO(255, 255, 255, 0.05), hover: isLight ? const Color.fromRGBO(15, 23, 32, 0.04) : const Color.fromRGBO(255, 255, 255, 0.10), shadowSoft: isLight ? const Color.fromRGBO(0, 0, 0, 0.08) : const Color.fromRGBO(0, 0, 0, 0.25), shadowDim: isLight ? const Color.fromARGB(40, 0, 0, 0) : const Color.fromARGB(54, 0, 0, 0), destructiveAccent: Colors.redAccent, textOnAccent: isLight ? Colors.white : Colors.black, overlay: isLight ? const Color.fromARGB(120, 0, 0, 0) : const Color.fromARGB(140, 0, 0, 0), transparent: Colors.transparent, dragTargetBorder: isLight ? const Color(0xFF1565C0) : const Color(0xFF42A5F5), syncPreparing: isLight ? const Color.fromARGB(255, 120, 120, 120) : const Color.fromARGB(255, 165, 165, 165), syncEncrypting: isLight ? const Color.fromARGB(255, 2, 136, 209) : const Color.fromARGB(255, 109, 191, 255), syncUploading: isLight ? const Color.fromARGB(255, 2, 119, 189) : const Color.fromARGB(255, 98, 190, 255), syncWaiting: const Color.fromARGB(255, 150, 150, 150), syncDecrypting: isLight ? const Color.fromARGB(255, 76, 175, 80) : const Color.fromARGB(255, 154, 194, 112), success: Colors.green, ); } }