refactor(legacy): migrate theming to Material 3 + SfColors extension

Replace the ThemePort/ThemeCode abstraction (GetIt-registered adapter)
with a Riverpod-driven Material 3 ColorScheme, an SfColors ThemeExtension
for brand tokens, and a user-facing appearance selector for light/dark/
system modes. Persisted via SharedPreferences, reacts to system
brightness changes. Payments mode keeps the existing ThemePort API.

Highlights
- New legacy_theme package: LegacyAppTheme (light/dark), LegacyColorSchemes,
  SfColors ThemeExtension, LegacyThemePreferences, LegacyThemeNotifier,
  LegacyThemeSelector. Timeframe-based variants scaffolded but disabled.
- New /legacy/dashboard/control_panel/settings/appearance route + screen.
- MaterialApp.router picks the legacy theme only when isLegacyMode.
- ~90 ThemeCode.* usages migrated to colorScheme.* / context.sfColors.*.
- 25 widgets dropped the 'ThemePort theme' constructor param.
- ~145 hardcoded colors migrated (exact hex 1:1, grey.shade tiers,
  destructive red -> colorScheme.error, background whites -> surface).
  Content-over-color whites, transparents, and brand semantic reds/
  oranges/greens intentionally preserved.
- sf_localizations updated with appearance / appearanceDescription keys
  in all six locales.
This commit is contained in:
2026-04-19 04:47:22 +02:00
parent bd7c47351f
commit f7d3dbfd27
175 changed files with 1722 additions and 1015 deletions

View File

@@ -91,6 +91,7 @@ class AppRoutes {
static const deleteAccount = '$accountSettings/delete_account';
static const settings = '$controlPanel/settings';
static const appearance = '$settings/appearance';
static const alarm = '$settings/alarm';
static const appStore = '$settings/app_store';
static const battery = '$settings/battery';

View File

@@ -1,5 +1,7 @@
{
"example": "Beispiel",
"appearance": "Erscheinungsbild",
"appearanceDescription": "Wählen Sie das Erscheinungsbild, das Ihren Vorlieben am besten entspricht. System folgt automatisch dem Thema Ihres Geräts.",
"start": "Starten",
"next": "Weiter",
"skip": "Überspringen",

View File

@@ -1,5 +1,7 @@
{
"example": "example",
"appearance": "Appearance",
"appearanceDescription": "Choose the appearance that best matches your preference. System follows your device theme automatically.",
"onboardingTitle1": "Real-time device location",
"onboardingSubtitle1": "Don't miss a thing.\nAccess your device's location in real time wherever you are.",
"onboardingTitle2": "Safety Zone",

View File

@@ -1,5 +1,7 @@
{
"example": "ejemplo",
"appearance": "Apariencia",
"appearanceDescription": "Elige la apariencia que mejor se adapte a tu preferencia. Sistema sigue automáticamente el tema de tu dispositivo.",
"onboardingTitle1": "Ubicación del dispositivo en tiempo real",
"onboardingSubtitle1": "No te pierdas nada.\nAccede a la ubicación de tu dispositivo en tiempo real estés donde estés.",
"onboardingTitle2": "Zona segura",

View File

@@ -1,5 +1,7 @@
{
"example": "exemple",
"appearance": "Apparence",
"appearanceDescription": "Choisissez l'apparence qui correspond le mieux à vos préférences. Système suit automatiquement le thème de votre appareil.",
"start": "Commencer",
"next": "Suivant",
"skip": "Passer",

View File

@@ -1,5 +1,7 @@
{
"example": "esempio",
"appearance": "Aspetto",
"appearanceDescription": "Scegli l'aspetto che meglio corrisponde alle tue preferenze. Sistema segue automaticamente il tema del tuo dispositivo.",
"start": "Inizia",
"next": "Avanti",
"skip": "Salta",

View File

@@ -1,5 +1,7 @@
{
"example": "exemplo",
"appearance": "Aparência",
"appearanceDescription": "Escolha a aparência que melhor se adapta à sua preferência. Sistema segue automaticamente o tema do seu dispositivo.",
"start": "Começar",
"next": "Próximo",
"skip": "Pular",

View File

@@ -33,6 +33,8 @@ class I18n {
static const String addNewSaveFamilyDevice = 'addNewSaveFamilyDevice';
static const String addressCountryHint = 'addressCountryHint';
static const String addressCountryLabel = 'addressCountryLabel';
static const String appearance = 'appearance';
static const String appearanceDescription = 'appearanceDescription';
static const String addSosContact = 'addSosContact';
static const String addWifiNetwork = 'addWifiNetwork';
static const String alarm = 'alarm';