diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..b0b3e1fe2543143896ee06ae7b9984f8bd038f73
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,18 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.json]
+indent_size = 2
+
+[*.yaml]
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.gitignore b/.gitignore
index 361df94f91db934b411ea13244ac8db6f41f3888..54ae0222de3e722adfb2b48c14d77c4d074dafda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
 .buildlog/
 .history
 .svn/
+migrate_working_dir/
 
 # IntelliJ related
 *.iml
diff --git a/assets/fonts/Nunito-Bold.ttf b/assets/fonts/Nunito-Bold.ttf
deleted file mode 100644
index 6519feb781449ebe0015cbc74dfd9e13110fbba9..0000000000000000000000000000000000000000
Binary files a/assets/fonts/Nunito-Bold.ttf and /dev/null differ
diff --git a/assets/fonts/Nunito-Light.ttf b/assets/fonts/Nunito-Light.ttf
deleted file mode 100644
index 8a0736c41cd6c2a1225d356bf274de1d0afc3497..0000000000000000000000000000000000000000
Binary files a/assets/fonts/Nunito-Light.ttf and /dev/null differ
diff --git a/assets/fonts/Nunito-Medium.ttf b/assets/fonts/Nunito-Medium.ttf
deleted file mode 100644
index 88fccdc0638b6f5d6ac49d9d269dc3d518618ad1..0000000000000000000000000000000000000000
Binary files a/assets/fonts/Nunito-Medium.ttf and /dev/null differ
diff --git a/assets/fonts/Nunito-Regular.ttf b/assets/fonts/Nunito-Regular.ttf
deleted file mode 100644
index e7b8375a896ef0cd8e06730a78c84532b377e784..0000000000000000000000000000000000000000
Binary files a/assets/fonts/Nunito-Regular.ttf and /dev/null differ
diff --git a/fastlane/metadata/android/en-US/changelogs/64.txt b/fastlane/metadata/android/en-US/changelogs/64.txt
new file mode 100644
index 0000000000000000000000000000000000000000..65ba5e83570223adc45ccea599a3487b24b8a7dd
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/64.txt
@@ -0,0 +1 @@
+Use flutter_custom_toolbox for common features.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/64.txt b/fastlane/metadata/android/fr-FR/changelogs/64.txt
new file mode 100644
index 0000000000000000000000000000000000000000..258c624fb3898d91b6b70d7d99db2719c1bf0751
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/64.txt
@@ -0,0 +1 @@
+Utilisation de flutter_custom_toolbox pour les fonctionnalités communes.
diff --git a/lib/config/screen.dart b/lib/config/screen.dart
index 2846969b1474a42a8c49892c528d2402134ee880..da777c0b3b9a371acb1b59986dbce42b72d9c192 100644
--- a/lib/config/screen.dart
+++ b/lib/config/screen.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/ui/screens/about.dart';
 import 'package:scrobbles/ui/screens/activity.dart';
diff --git a/lib/config/theme.dart b/lib/config/theme.dart
deleted file mode 100644
index 138460e58f89bc93afb0899d6cfe8f8e662a466f..0000000000000000000000000000000000000000
--- a/lib/config/theme.dart
+++ /dev/null
@@ -1,192 +0,0 @@
-import 'package:flutter/material.dart';
-
-/// Colors from Tailwind CSS (v3.0) - June 2022
-///
-/// https://tailwindcss.com/docs/customizing-colors
-
-const int _primaryColor = 0xFF6366F1;
-const MaterialColor primarySwatch = MaterialColor(_primaryColor, <int, Color>{
-  50: Color(0xFFEEF2FF), // indigo-50
-  100: Color(0xFFE0E7FF), // indigo-100
-  200: Color(0xFFC7D2FE), // indigo-200
-  300: Color(0xFFA5B4FC), // indigo-300
-  400: Color(0xFF818CF8), // indigo-400
-  500: Color(_primaryColor), // indigo-500
-  600: Color(0xFF4F46E5), // indigo-600
-  700: Color(0xFF4338CA), // indigo-700
-  800: Color(0xFF3730A3), // indigo-800
-  900: Color(0xFF312E81), // indigo-900
-});
-
-const int _textColor = 0xFF64748B;
-const MaterialColor textSwatch = MaterialColor(_textColor, <int, Color>{
-  50: Color(0xFFF8FAFC), // slate-50
-  100: Color(0xFFF1F5F9), // slate-100
-  200: Color(0xFFE2E8F0), // slate-200
-  300: Color(0xFFCBD5E1), // slate-300
-  400: Color(0xFF94A3B8), // slate-400
-  500: Color(_textColor), // slate-500
-  600: Color(0xFF475569), // slate-600
-  700: Color(0xFF334155), // slate-700
-  800: Color(0xFF1E293B), // slate-800
-  900: Color(0xFF0F172A), // slate-900
-});
-
-const Color errorColor = Color(0xFFDC2626); // red-600
-
-final ColorScheme lightColorScheme = ColorScheme.light(
-  primary: primarySwatch.shade500,
-  secondary: primarySwatch.shade500,
-  onSecondary: Colors.white,
-  error: errorColor,
-  onSurface: textSwatch.shade500,
-  surface: textSwatch.shade50,
-  surfaceContainerHighest: Colors.white,
-  shadow: textSwatch.shade900.withOpacity(.1),
-);
-
-final ColorScheme darkColorScheme = ColorScheme.dark(
-  primary: primarySwatch.shade500,
-  secondary: primarySwatch.shade500,
-  onSecondary: Colors.white,
-  error: errorColor,
-  onSurface: textSwatch.shade300,
-  surface: const Color(0xFF262630),
-  surfaceContainerHighest: const Color(0xFF282832),
-  shadow: textSwatch.shade900.withOpacity(.2),
-);
-
-final ThemeData lightTheme = ThemeData(
-  colorScheme: lightColorScheme,
-  fontFamily: 'Nunito',
-  textTheme: TextTheme(
-    displayLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    displayMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    displaySmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    headlineLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    headlineMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    headlineSmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    titleLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    titleMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    titleSmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    bodyLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    bodyMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    bodySmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    labelLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    labelMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    labelSmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-  ),
-);
-
-final ThemeData darkTheme = lightTheme.copyWith(
-  colorScheme: darkColorScheme,
-  textTheme: TextTheme(
-    displayLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    displayMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    displaySmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    headlineLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    headlineMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    headlineSmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    titleLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    titleMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    titleSmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    bodyLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    bodyMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    bodySmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    labelLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    labelMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    labelSmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-  ),
-);
-
-final ThemeData appTheme = darkTheme;
diff --git a/lib/cubit/data_counts_by_day_cubit.dart b/lib/cubit/data_counts_by_day_cubit.dart
index c2746cfc39f42e466b5fe97170362980ff271e33..a676e4bc3ab1a6acd1815f977586f1f268e502ed 100644
--- a/lib/cubit/data_counts_by_day_cubit.dart
+++ b/lib/cubit/data_counts_by_day_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/counts_by_day.dart';
diff --git a/lib/cubit/data_counts_by_hour_cubit.dart b/lib/cubit/data_counts_by_hour_cubit.dart
index e4c477092a48cc0862e629728d7fa44dd39fac0c..7d817829580c0d1e1887dbebb649b5ff10c9e756 100644
--- a/lib/cubit/data_counts_by_hour_cubit.dart
+++ b/lib/cubit/data_counts_by_hour_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/counts_by_hour.dart';
diff --git a/lib/cubit/data_discoveries_cubit.dart b/lib/cubit/data_discoveries_cubit.dart
index e3acd5392647f218fc5cbcc2eb1f5dcfdd671cdd..561f32d9efff848f83fb0e7ed9e4aadb8bca0ca3 100644
--- a/lib/cubit/data_discoveries_cubit.dart
+++ b/lib/cubit/data_discoveries_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/discoveries.dart';
diff --git a/lib/cubit/data_heatmap_cubit.dart b/lib/cubit/data_heatmap_cubit.dart
index dc7e4648d8cf5143d516caae53a96f106f8f0178..3fe1d99c82a3be45db9140e0ce04a5eedcff31c9 100644
--- a/lib/cubit/data_heatmap_cubit.dart
+++ b/lib/cubit/data_heatmap_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/heatmap.dart';
diff --git a/lib/cubit/data_new_artists_cubit.dart b/lib/cubit/data_new_artists_cubit.dart
index c858321c19daae38884112a9be58ae54af80b9ea..c01f2f7b12d1f774830e598fd50f444d7fb7237b 100644
--- a/lib/cubit/data_new_artists_cubit.dart
+++ b/lib/cubit/data_new_artists_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/new_artists.dart';
diff --git a/lib/cubit/data_new_tracks_cubit.dart b/lib/cubit/data_new_tracks_cubit.dart
index d1c1e76925fb3ba836baa9e79e9455d105dc5240..f786af4641c2efc8ade9f3ab58b61891b50c804b 100644
--- a/lib/cubit/data_new_tracks_cubit.dart
+++ b/lib/cubit/data_new_tracks_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/new_tracks.dart';
diff --git a/lib/cubit/data_statistics_global_cubit.dart b/lib/cubit/data_statistics_global_cubit.dart
index e441c4ee26f05a23a743618033ce529e8b60a209..466b7a99ec619296c5c5b874fb4eabb4d88c0251 100644
--- a/lib/cubit/data_statistics_global_cubit.dart
+++ b/lib/cubit/data_statistics_global_cubit.dart
@@ -1,6 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/models/data/statistics_global.dart';
 import 'package:scrobbles/network/scrobbles.dart';
diff --git a/lib/cubit/data_statistics_recent_cubit.dart b/lib/cubit/data_statistics_recent_cubit.dart
index c950f64b046f57e19295f5d33925c3280c12f93d..86a5def9774d26123670886e22ba13c55a20c918 100644
--- a/lib/cubit/data_statistics_recent_cubit.dart
+++ b/lib/cubit/data_statistics_recent_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/statistics_recent.dart';
diff --git a/lib/cubit/data_timeline_cubit.dart b/lib/cubit/data_timeline_cubit.dart
index c82a0d686683be37292ff7c133682fcc3e6935cb..45a1bbb0c80997ad0336d8747173b451d31e97d7 100644
--- a/lib/cubit/data_timeline_cubit.dart
+++ b/lib/cubit/data_timeline_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/timeline.dart';
diff --git a/lib/cubit/data_top_artists_cubit.dart b/lib/cubit/data_top_artists_cubit.dart
index c8850eaee028a35feded2e965af7aaa404d865b3..b67fade4a6d9a5570be30850982dde7ba3a9e3ed 100644
--- a/lib/cubit/data_top_artists_cubit.dart
+++ b/lib/cubit/data_top_artists_cubit.dart
@@ -1,7 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
 import 'package:scrobbles/models/data/topartists.dart';
diff --git a/lib/cubit/nav_cubit_pages.dart b/lib/cubit/nav_cubit_pages.dart
index 4caca488df3fdd01091e7c7e967a5152010f2b33..10d729d75d43608c790aa608706bfb86e56d09a7 100644
--- a/lib/cubit/nav_cubit_pages.dart
+++ b/lib/cubit/nav_cubit_pages.dart
@@ -1,4 +1,4 @@
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/config/activity_page.dart';
 
diff --git a/lib/cubit/nav_cubit_screens.dart b/lib/cubit/nav_cubit_screens.dart
index 43a941f44d1e53e12d533ac957a5d2eb1efe1b78..4376701ab49c280e30ae387c2980aa4414792080 100644
--- a/lib/cubit/nav_cubit_screens.dart
+++ b/lib/cubit/nav_cubit_screens.dart
@@ -1,4 +1,4 @@
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/config/screen.dart';
 
diff --git a/lib/cubit/settings_global_cubit.dart b/lib/cubit/settings_global_cubit.dart
index f45d5dad21b87d8b6fda9fff4a90ac66653158ee..75f948973e28de71c1f7b97e3dbafd1878ac9241 100644
--- a/lib/cubit/settings_global_cubit.dart
+++ b/lib/cubit/settings_global_cubit.dart
@@ -1,6 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/config/default_global_settings.dart';
 
diff --git a/lib/cubit/theme_cubit.dart b/lib/cubit/theme_cubit.dart
index b793e895dbb0c672d451cd403e0036c3d9ac9b42..1ecab6014c67a0393eabbf704b8b85c9e988705e 100644
--- a/lib/cubit/theme_cubit.dart
+++ b/lib/cubit/theme_cubit.dart
@@ -1,6 +1,5 @@
-import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 part 'theme_state.dart';
 
diff --git a/lib/main.dart b/lib/main.dart
index 01c4a4340e63173cd6c3646259ee33d1c6f9bde8..4b23560f2e4dc8e9f9b8cd606fa3308e50154a08 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,14 +1,9 @@
 import 'dart:io';
 
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hive/hive.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
-import 'package:path_provider/path_provider.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:scrobbles/config/theme.dart';
 import 'package:scrobbles/cubit/nav_cubit_pages.dart';
 import 'package:scrobbles/cubit/nav_cubit_screens.dart';
 import 'package:scrobbles/cubit/data_counts_by_day_cubit.dart';
diff --git a/lib/ui/helpers/app_titles.dart b/lib/ui/helpers/app_titles.dart
deleted file mode 100644
index e1bb6b0baaa622ce532ca7f4e7911d1f538a3c0b..0000000000000000000000000000000000000000
--- a/lib/ui/helpers/app_titles.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-
-class AppHeader extends StatelessWidget {
-  const AppHeader({super.key, required this.text});
-
-  final String text;
-
-  @override
-  Widget build(BuildContext context) {
-    return Text(
-      tr(text),
-      textAlign: TextAlign.start,
-      style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
-    );
-  }
-}
-
-class AppTitle extends StatelessWidget {
-  const AppTitle({super.key, required this.text});
-
-  final String text;
-
-  @override
-  Widget build(BuildContext context) {
-    return Text(
-      text,
-      textAlign: TextAlign.start,
-      style: Theme.of(context).textTheme.titleLarge!.apply(fontWeightDelta: 2),
-    );
-  }
-}
diff --git a/lib/ui/nav/bottom_nav_bar.dart b/lib/ui/nav/bottom_nav_bar.dart
index 1cdade62858ef454bfc38b81f15362c677f91d26..f6d47390df3c30316cb974fe7727b1392149dd40 100644
--- a/lib/ui/nav/bottom_nav_bar.dart
+++ b/lib/ui/nav/bottom_nav_bar.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter_swipe/flutter_swipe.dart';
 
 import 'package:scrobbles/config/activity_page.dart';
@@ -36,7 +35,7 @@ class BottomNavBar extends StatelessWidget {
           return BottomNavigationBar(
             currentIndex: pageIndex,
             onTap: (int index) {
-              context.read<NavCubitPage>().updateIndex(index);
+              BlocProvider.of<NavCubitPage>(context).updateIndex(index);
               swipeController.move(index);
             },
             type: BottomNavigationBarType.fixed,
diff --git a/lib/ui/nav/global_app_bar.dart b/lib/ui/nav/global_app_bar.dart
index 7d6ee4274968b3e491066795cbdea475a81e892a..542643f38953271db04ac004db203d2859cd85b1 100644
--- a/lib/ui/nav/global_app_bar.dart
+++ b/lib/ui/nav/global_app_bar.dart
@@ -1,6 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_counts_by_day_cubit.dart';
 import 'package:scrobbles/cubit/data_counts_by_hour_cubit.dart';
@@ -15,7 +14,6 @@ import 'package:scrobbles/cubit/data_top_artists_cubit.dart';
 import 'package:scrobbles/cubit/nav_cubit_pages.dart';
 import 'package:scrobbles/config/screen.dart';
 import 'package:scrobbles/cubit/nav_cubit_screens.dart';
-import 'package:scrobbles/ui/helpers/app_titles.dart';
 
 class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
   const GlobalAppBar({super.key});
@@ -30,7 +28,7 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
           // go to Settings page
           menuActions.add(IconButton(
             onPressed: () {
-              context.read<NavCubitScreen>().goToSettingsPage();
+              BlocProvider.of<NavCubitScreen>(context).goToSettingsPage();
             },
             icon: Screen.screenSettings.icon,
           ));
@@ -38,7 +36,7 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
           // go to About page
           menuActions.add(IconButton(
             onPressed: () {
-              context.read<NavCubitScreen>().goToAboutPage();
+              BlocProvider.of<NavCubitScreen>(context).goToAboutPage();
             },
             icon: Screen.screenAbout.icon,
           ));
@@ -63,8 +61,8 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
           // back to Home page
           menuActions.add(IconButton(
             onPressed: () {
-              context.read<NavCubitScreen>().goToActivityPage();
-              context.read<NavCubitPage>().goToHomePage();
+              BlocProvider.of<NavCubitScreen>(context).goToActivityPage();
+              BlocProvider.of<NavCubitPage>(context).goToHomePage();
             },
             icon: Screen.screenActivity.icon,
           ));
diff --git a/lib/ui/pages/discoveries.dart b/lib/ui/pages/discoveries.dart
index 34b02515255c62da3417159de922060a1d0228a3..1df3ff94af915292e9b44ff4c9da94c7b5adb4d8 100644
--- a/lib/ui/pages/discoveries.dart
+++ b/lib/ui/pages/discoveries.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_discoveries_cubit.dart';
 import 'package:scrobbles/cubit/data_new_artists_cubit.dart';
diff --git a/lib/ui/pages/home.dart b/lib/ui/pages/home.dart
index f1d647add38e5c2df981723a09dedfa2c48bd678..c28f4a0346cf3505c9edbdf80a75aa9aa64fe36b 100644
--- a/lib/ui/pages/home.dart
+++ b/lib/ui/pages/home.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_statistics_global_cubit.dart';
 import 'package:scrobbles/cubit/data_statistics_recent_cubit.dart';
diff --git a/lib/ui/pages/statistics.dart b/lib/ui/pages/statistics.dart
index b232bf0e9a29cc97e29cfb8fe3051d5e715baf7d..f96aba468101c1b967353e2d5823028e639aaa3e 100644
--- a/lib/ui/pages/statistics.dart
+++ b/lib/ui/pages/statistics.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_counts_by_day_cubit.dart';
 import 'package:scrobbles/cubit/data_counts_by_hour_cubit.dart';
diff --git a/lib/ui/screens/about.dart b/lib/ui/screens/about.dart
index a60396cba3f0d91214f4ddb6a4dc06d12ace536a..85c38c32d997fc8be43bca5514a2dbd5831bf7d7 100644
--- a/lib/ui/screens/about.dart
+++ b/lib/ui/screens/about.dart
@@ -1,8 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:package_info_plus/package_info_plus.dart';
-
-import 'package:scrobbles/ui/helpers/app_titles.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 class ScreenAbout extends StatelessWidget {
   const ScreenAbout({super.key});
diff --git a/lib/ui/screens/activity.dart b/lib/ui/screens/activity.dart
index 7ebabc1eb9cbabe088c83e8a77979cb69465be8d..c8db336bcfcd67330b657bb825c31e9c48ffa058 100644
--- a/lib/ui/screens/activity.dart
+++ b/lib/ui/screens/activity.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter_swipe/flutter_swipe.dart';
 
 import 'package:scrobbles/config/activity_page.dart';
diff --git a/lib/ui/screens/settings.dart b/lib/ui/screens/settings.dart
index 856ad882a681a2d8d765165b8f57d45a53a07528..678e2901cfbdd06df0bb0ecd088b98f0198d1776 100644
--- a/lib/ui/screens/settings.dart
+++ b/lib/ui/screens/settings.dart
@@ -1,7 +1,6 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:scrobbles/ui/helpers/app_titles.dart';
 import 'package:scrobbles/ui/settings/settings_form.dart';
 
 class ScreenSettings extends StatelessWidget {
diff --git a/lib/ui/settings/settings_form.dart b/lib/ui/settings/settings_form.dart
index f64158547afe53aef126a63f66f758452244fd8c..1ef9da0ac55faa5721dccb6347d01e19a5811638 100644
--- a/lib/ui/settings/settings_form.dart
+++ b/lib/ui/settings/settings_form.dart
@@ -1,12 +1,9 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:scrobbles/ui/settings/theme_card.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/config/default_global_settings.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
-import 'package:scrobbles/ui/helpers/app_titles.dart';
+import 'package:scrobbles/ui/settings/theme_card.dart';
 
 class SettingsForm extends StatefulWidget {
   const SettingsForm({super.key});
diff --git a/lib/ui/settings/theme_card.dart b/lib/ui/settings/theme_card.dart
index 738541d400cf312b7a1b657ff68bf22b1895f3ac..20d56d4481f2713b2052c5d1e93852954f033954 100644
--- a/lib/ui/settings/theme_card.dart
+++ b/lib/ui/settings/theme_card.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/theme_cubit.dart';
 
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index 6d765f6dfb85f3817bc99acffe99d256cf54f020..3bb0c805400db0c2745159d523977bd55ccdfd05 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/config/screen.dart';
 import 'package:scrobbles/cubit/nav_cubit_screens.dart';
diff --git a/lib/ui/widgets/abstracts/custom_bar_chart.dart b/lib/ui/widgets/abstracts/custom_bar_chart.dart
index 9b304a7f29ba6f491cb2672076b4f81bb9d1a3f3..ab6e595a4fc1469f99b99adffdbd458455bc204b 100644
--- a/lib/ui/widgets/abstracts/custom_bar_chart.dart
+++ b/lib/ui/widgets/abstracts/custom_bar_chart.dart
@@ -1,8 +1,8 @@
-import 'package:fl_chart/fl_chart.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+import 'package:fl_chart/fl_chart.dart';
 
 import 'package:scrobbles/ui/widgets/abstracts/custom_chart.dart';
-import 'package:scrobbles/utils/color_extensions.dart';
 
 class CustomBarChart extends CustomChart {
   const CustomBarChart({
diff --git a/lib/ui/widgets/abstracts/custom_chart.dart b/lib/ui/widgets/abstracts/custom_chart.dart
index 3d53fe1d0bccd06d0096615e19e7b0bb813a657a..d5768f22c3311469a14c3f0eed8d99ead6a7869d 100644
--- a/lib/ui/widgets/abstracts/custom_chart.dart
+++ b/lib/ui/widgets/abstracts/custom_chart.dart
@@ -1,6 +1,6 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:fl_chart/fl_chart.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/config/app_colors.dart';
 
diff --git a/lib/ui/widgets/card_content.dart b/lib/ui/widgets/card_content.dart
index 68587f70f622afc42aeb9908cb23c20f61b70137..c150fc001a3369e7d69afb8eeb3a49e3cd8cc80b 100644
--- a/lib/ui/widgets/card_content.dart
+++ b/lib/ui/widgets/card_content.dart
@@ -1,6 +1,5 @@
 import 'package:flutter/material.dart';
-
-import 'package:scrobbles/ui/helpers/app_titles.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 class CardContent extends StatelessWidget {
   const CardContent({
diff --git a/lib/ui/widgets/cards/counts_by_day.dart b/lib/ui/widgets/cards/counts_by_day.dart
index 917183ed62d13355e989b2a871fe88975d45e3ac..259fd29804c8316d577c1b511f0f83c24b01a8e6 100644
--- a/lib/ui/widgets/cards/counts_by_day.dart
+++ b/lib/ui/widgets/cards/counts_by_day.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_counts_by_day_cubit.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
diff --git a/lib/ui/widgets/cards/counts_by_hour.dart b/lib/ui/widgets/cards/counts_by_hour.dart
index 6931246700a8d53a8cc54af1808e0bf7c87769dd..dee7584d05e1c2b12bf44a810f791a42502b89f5 100644
--- a/lib/ui/widgets/cards/counts_by_hour.dart
+++ b/lib/ui/widgets/cards/counts_by_hour.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_counts_by_hour_cubit.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
diff --git a/lib/ui/widgets/cards/discoveries.dart b/lib/ui/widgets/cards/discoveries.dart
index c0ec4852a5fe77caacc764f57365be2aa4e35bf4..d1e4baf4734e153eaac9297b05abd040499fadad 100644
--- a/lib/ui/widgets/cards/discoveries.dart
+++ b/lib/ui/widgets/cards/discoveries.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_discoveries_cubit.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
diff --git a/lib/ui/widgets/cards/heatmap.dart b/lib/ui/widgets/cards/heatmap.dart
index e89318bc6f826cd36c1a1edf698c5b62a0890a86..e51a6670af44c02bf2b3cbe44e0a180884bb4a8a 100644
--- a/lib/ui/widgets/cards/heatmap.dart
+++ b/lib/ui/widgets/cards/heatmap.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_heatmap_cubit.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
diff --git a/lib/ui/widgets/cards/new_artists.dart b/lib/ui/widgets/cards/new_artists.dart
index 6c931373494bb84c74f63883dbd1d5305487fac2..365d5d6ef23381af434dc4e40d6eec4053469015 100644
--- a/lib/ui/widgets/cards/new_artists.dart
+++ b/lib/ui/widgets/cards/new_artists.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_new_artists_cubit.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
diff --git a/lib/ui/widgets/cards/new_tracks.dart b/lib/ui/widgets/cards/new_tracks.dart
index 28c89e66d96344bf0535f6d6ee13310764a52fc7..0a73fd3b0e76d50cff3ff3c5a42e25a46fb701f6 100644
--- a/lib/ui/widgets/cards/new_tracks.dart
+++ b/lib/ui/widgets/cards/new_tracks.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_new_tracks_cubit.dart';
 import 'package:scrobbles/ui/widgets/card_content.dart';
diff --git a/lib/ui/widgets/cards/statistics_global.dart b/lib/ui/widgets/cards/statistics_global.dart
index 0d920f740d2392bf955b761ef9efc25307c6b08d..a1480cd44a9464791e8fa5e224d02d8ac5379613 100644
--- a/lib/ui/widgets/cards/statistics_global.dart
+++ b/lib/ui/widgets/cards/statistics_global.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_statistics_global_cubit.dart';
 import 'package:scrobbles/models/data/statistics_global.dart';
diff --git a/lib/ui/widgets/cards/statistics_recent.dart b/lib/ui/widgets/cards/statistics_recent.dart
index c04bf23aab0e3daf380f4475989af03b87b9dc51..e3312da69f12f203ac0271e348f1d909cb7ae8f2 100644
--- a/lib/ui/widgets/cards/statistics_recent.dart
+++ b/lib/ui/widgets/cards/statistics_recent.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_statistics_recent_cubit.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
diff --git a/lib/ui/widgets/cards/timeline.dart b/lib/ui/widgets/cards/timeline.dart
index 9524a10210256006fe960ff6f2e01f47b7fb14b0..cf9d6888559c6dd94cb424dc6d360c3e9509d99f 100644
--- a/lib/ui/widgets/cards/timeline.dart
+++ b/lib/ui/widgets/cards/timeline.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_timeline_cubit.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
diff --git a/lib/ui/widgets/cards/top_artists.dart b/lib/ui/widgets/cards/top_artists.dart
index 20a50e9ca6425789e56022385f8106f7d7b2cb57..a58127c4be74aac2474ff98c0256c228b7deae11 100644
--- a/lib/ui/widgets/cards/top_artists.dart
+++ b/lib/ui/widgets/cards/top_artists.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/cubit/data_top_artists_cubit.dart';
 import 'package:scrobbles/cubit/settings_global_cubit.dart';
diff --git a/lib/ui/widgets/charts/counts_by_hour.dart b/lib/ui/widgets/charts/counts_by_hour.dart
index a4c575cace8d78691f980751d02a3da22d779a03..e8730f5315da42c7779aa2de6d15375db50dd175 100644
--- a/lib/ui/widgets/charts/counts_by_hour.dart
+++ b/lib/ui/widgets/charts/counts_by_hour.dart
@@ -1,10 +1,10 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:fl_chart/fl_chart.dart';
 
 import 'package:scrobbles/config/app_colors.dart';
 import 'package:scrobbles/models/data/counts_by_hour.dart';
 import 'package:scrobbles/ui/widgets/abstracts/custom_bar_chart.dart';
-import 'package:scrobbles/utils/color_extensions.dart';
 
 class ChartCountsByHour extends CustomBarChart {
   const ChartCountsByHour({
diff --git a/lib/ui/widgets/charts/discoveries_artists.dart b/lib/ui/widgets/charts/discoveries_artists.dart
index 75a4034b3da2fa4ce8cf9f43a81d71191c5a4616..927163a9b8d99859316baef30c9aee640a745fbb 100644
--- a/lib/ui/widgets/charts/discoveries_artists.dart
+++ b/lib/ui/widgets/charts/discoveries_artists.dart
@@ -1,10 +1,10 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:fl_chart/fl_chart.dart';
 
 import 'package:scrobbles/config/app_colors.dart';
 import 'package:scrobbles/models/data/discoveries.dart';
 import 'package:scrobbles/ui/widgets/abstracts/custom_bar_chart.dart';
-import 'package:scrobbles/utils/color_extensions.dart';
 
 class ChartDiscoveriesArtists extends CustomBarChart {
   const ChartDiscoveriesArtists({super.key, required this.chartData});
diff --git a/lib/ui/widgets/charts/discoveries_tracks.dart b/lib/ui/widgets/charts/discoveries_tracks.dart
index eae77f8946e09982e599288d75750a83f57c29c5..a5fa9aa707b33e8f91474fa6e1e3f01016a43817 100644
--- a/lib/ui/widgets/charts/discoveries_tracks.dart
+++ b/lib/ui/widgets/charts/discoveries_tracks.dart
@@ -1,10 +1,10 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:fl_chart/fl_chart.dart';
 
 import 'package:scrobbles/config/app_colors.dart';
 import 'package:scrobbles/models/data/discoveries.dart';
 import 'package:scrobbles/ui/widgets/abstracts/custom_bar_chart.dart';
-import 'package:scrobbles/utils/color_extensions.dart';
 
 class ChartDiscoveriesTracks extends CustomBarChart {
   const ChartDiscoveriesTracks({super.key, required this.chartData});
diff --git a/lib/ui/widgets/charts/heatmap.dart b/lib/ui/widgets/charts/heatmap.dart
index fcb34155ff87c3d4145ed691c938c5285ca76bba..0e7963e380887ffdbddd67269c32aa144bd81723 100644
--- a/lib/ui/widgets/charts/heatmap.dart
+++ b/lib/ui/widgets/charts/heatmap.dart
@@ -1,6 +1,6 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:fl_chart/fl_chart.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/config/app_colors.dart';
 import 'package:scrobbles/models/data/heatmap.dart';
diff --git a/lib/ui/widgets/charts/timeline_eclecticism.dart b/lib/ui/widgets/charts/timeline_eclecticism.dart
index bab15c0dd5dbf42fb591db199e6cd63538366376..9403ffc6b0ebd3f3cceaf87df25a7bcb772b45bb 100644
--- a/lib/ui/widgets/charts/timeline_eclecticism.dart
+++ b/lib/ui/widgets/charts/timeline_eclecticism.dart
@@ -1,10 +1,10 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:fl_chart/fl_chart.dart';
 
 import 'package:scrobbles/config/app_colors.dart';
 import 'package:scrobbles/models/data/timeline.dart';
 import 'package:scrobbles/ui/widgets/abstracts/custom_line_chart.dart';
-import 'package:scrobbles/utils/color_extensions.dart';
 
 class ChartTimelineEclecticism extends CustomLineChart {
   const ChartTimelineEclecticism({super.key, required this.chartData});
diff --git a/lib/ui/widgets/charts/top_artists.dart b/lib/ui/widgets/charts/top_artists.dart
index f3a0181ad6e3000955f225e976fd154ffa0ec7c1..179ca7fcf124be12dc2b46ffccfe273064dbb9f5 100644
--- a/lib/ui/widgets/charts/top_artists.dart
+++ b/lib/ui/widgets/charts/top_artists.dart
@@ -1,9 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:fl_chart/fl_chart.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/models/data/topartists.dart';
 import 'package:scrobbles/ui/widgets/abstracts/custom_chart.dart';
-import 'package:scrobbles/utils/color_extensions.dart';
 
 class ChartTopArtists extends CustomChart {
   const ChartTopArtists({super.key, required this.chartData});
diff --git a/lib/ui/widgets/charts/top_artists_stream.dart b/lib/ui/widgets/charts/top_artists_stream.dart
index 4f657e70d0763cefbc42dd7dbb0a523b57773275..029d980cfb4bb42754a487ec5ab6f88cda329391 100644
--- a/lib/ui/widgets/charts/top_artists_stream.dart
+++ b/lib/ui/widgets/charts/top_artists_stream.dart
@@ -1,9 +1,9 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:fl_chart/fl_chart.dart';
 
 import 'package:scrobbles/models/data/topartists.dart';
 import 'package:scrobbles/ui/widgets/abstracts/custom_line_chart.dart';
-import 'package:scrobbles/utils/color_extensions.dart';
 
 class ChartTopArtistsStream extends CustomLineChart {
   const ChartTopArtistsStream({super.key, required this.chartData});
diff --git a/lib/ui/widgets/content/statistics_global.dart b/lib/ui/widgets/content/statistics_global.dart
index 5da9330783cfaabd2962120b19ded32391b685ce..a7e8f2e0248c81a61939c03e6568003d468baf9b 100644
--- a/lib/ui/widgets/content/statistics_global.dart
+++ b/lib/ui/widgets/content/statistics_global.dart
@@ -1,5 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/models/data/statistics_global.dart';
 
diff --git a/lib/ui/widgets/content/statistics_recent.dart b/lib/ui/widgets/content/statistics_recent.dart
index 6c9ba8618333081b5530677bb5996a27a8edb694..77b499edb776886d2c975153d4e059d746c982aa 100644
--- a/lib/ui/widgets/content/statistics_recent.dart
+++ b/lib/ui/widgets/content/statistics_recent.dart
@@ -1,5 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:scrobbles/models/data/statistics_recent.dart';
 
diff --git a/lib/utils/color_extensions.dart b/lib/utils/color_extensions.dart
deleted file mode 100644
index 4e55e338f0d3ed98b233d1ef887b7b3e17e29d97..0000000000000000000000000000000000000000
--- a/lib/utils/color_extensions.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-import 'dart:ui';
-
-extension ColorExtension on Color {
-  Color darken([int percent = 40]) {
-    assert(1 <= percent && percent <= 100);
-    final value = 1 - percent / 100;
-    return Color.fromARGB(
-      alpha,
-      (red * value).round(),
-      (green * value).round(),
-      (blue * value).round(),
-    );
-  }
-
-  Color lighten([int percent = 40]) {
-    assert(1 <= percent && percent <= 100);
-    final value = percent / 100;
-    return Color.fromARGB(
-      alpha,
-      (red + ((255 - red) * value)).round(),
-      (green + ((255 - green) * value)).round(),
-      (blue + ((255 - blue) * value)).round(),
-    );
-  }
-
-  Color avg(Color other) {
-    final red = (this.red + other.red) ~/ 2;
-    final green = (this.green + other.green) ~/ 2;
-    final blue = (this.blue + other.blue) ~/ 2;
-    final alpha = (this.alpha + other.alpha) ~/ 2;
-    return Color.fromARGB(alpha, red, green, blue);
-  }
-}
diff --git a/lib/utils/tools.dart b/lib/utils/tools.dart
deleted file mode 100644
index fd48b2b009b80b22248d6e7f08a63e96c4065bd7..0000000000000000000000000000000000000000
--- a/lib/utils/tools.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:flutter/foundation.dart';
-
-void printlog(String message) {
-  if (!kReleaseMode) {
-    debugPrint(message);
-  }
-}
diff --git a/pubspec.lock b/pubspec.lock
index 8521fa8dcc2b44478acecb23b92137be5a81e233..d78deabe4bdf57e3d5d957d9d5ea456cb5859f93 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,20 +5,20 @@ packages:
     dependency: transitive
     description:
       name: args
-      sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
+      sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
       url: "https://pub.dev"
     source: hosted
-    version: "2.5.0"
+    version: "2.6.0"
   async:
     dependency: transitive
     description:
       name: async
-      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+      sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
       url: "https://pub.dev"
     source: hosted
-    version: "2.11.0"
+    version: "2.12.0"
   auto_size_text:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: auto_size_text
       sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599"
@@ -61,12 +61,12 @@ packages:
     dependency: transitive
     description:
       name: crypto
-      sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
+      sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.5"
+    version: "3.0.6"
   easy_localization:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: easy_localization
       sha256: fa59bcdbbb911a764aa6acf96bbb6fa7a5cf8234354fc45ec1a43a0349ef0201
@@ -82,7 +82,7 @@ packages:
     source: hosted
     version: "0.0.2"
   equatable:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: equatable
       sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
@@ -119,13 +119,22 @@ packages:
     source: sdk
     version: "0.0.0"
   flutter_bloc:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: flutter_bloc
       sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
       url: "https://pub.dev"
     source: hosted
     version: "8.1.6"
+  flutter_custom_toolbox:
+    dependency: "direct main"
+    description:
+      path: "."
+      ref: "0.1.1"
+      resolved-ref: ba7137ca9edec7e503ed3dbfe7f6ede7e9cfbf4d
+      url: "https://git.harrault.fr/android/flutter-toolbox.git"
+    source: git
+    version: "0.1.1"
   flutter_lints:
     dependency: "direct dev"
     description:
@@ -153,7 +162,7 @@ packages:
     source: sdk
     version: "0.0.0"
   hive:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: hive
       sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
@@ -177,7 +186,7 @@ packages:
     source: hosted
     version: "4.0.2"
   hydrated_bloc:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: hydrated_bloc
       sha256: af35b357739fe41728df10bec03aad422cdc725a1e702e03af9d2a41ea05160c
@@ -233,13 +242,13 @@ packages:
     source: hosted
     version: "1.0.0"
   package_info_plus:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: package_info_plus
-      sha256: "894f37107424311bdae3e476552229476777b8752c5a2a2369c0cb9a2d5442ef"
+      sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998
       url: "https://pub.dev"
     source: hosted
-    version: "8.0.3"
+    version: "8.1.0"
   package_info_plus_platform_interface:
     dependency: transitive
     description:
@@ -257,7 +266,7 @@ packages:
     source: hosted
     version: "1.9.0"
   path_provider:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: path_provider
       sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
@@ -308,10 +317,10 @@ packages:
     dependency: transitive
     description:
       name: platform
-      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
+      sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.5"
+    version: "3.1.6"
   plugin_platform_interface:
     dependency: transitive
     description:
@@ -401,10 +410,10 @@ packages:
     dependency: transitive
     description:
       name: string_scanner
-      sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
+      sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6"
       url: "https://pub.dev"
     source: hosted
-    version: "1.3.0"
+    version: "1.4.0"
   synchronized:
     dependency: transitive
     description:
@@ -425,12 +434,12 @@ packages:
     dependency: transitive
     description:
       name: typed_data
-      sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
+      sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
       url: "https://pub.dev"
     source: hosted
-    version: "1.3.2"
+    version: "1.4.0"
   unicons:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: unicons
       sha256: f3eab9d87c226415ef857cfd2167e1d12ad81ea1f5783b46cf644224fea4eab7
@@ -457,10 +466,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: "4d45dc9069dba4619dc0ebd93c7cec5e66d8482cb625a370ac806dcc8165f2ec"
+      sha256: "2735daae5150e8b1dfeb3eb0544b4d3af0061e9e82cef063adcd583bdae4306a"
       url: "https://pub.dev"
     source: hosted
-    version: "5.5.5"
+    version: "5.7.0"
   xdg_directories:
     dependency: transitive
     description:
@@ -470,5 +479,5 @@ packages:
     source: hosted
     version: "1.1.0"
 sdks:
-  dart: ">=3.5.0 <4.0.0"
+  dart: ">=3.5.3 <4.0.0"
   flutter: ">=3.24.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index dd6f407184b551eac99111f2a814a4d4ce4cfcbc..7122faeb188357e222f6b80bd7bc6a54a3b85af7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Display scrobbles data and charts
 
 publish_to: "none"
 
-version: 0.2.2+63
+version: 0.3.0+64
 
 environment:
   sdk: "^3.0.0"
@@ -13,15 +13,10 @@ dependencies:
     sdk: flutter
 
   # base
-  auto_size_text: ^3.0.0
-  easy_localization: ^3.0.1
-  equatable: ^2.0.5
-  flutter_bloc: ^8.1.1
-  hive: ^2.2.3
-  hydrated_bloc: ^9.0.0
-  package_info_plus: ^8.0.0
-  path_provider: ^2.0.11
-  unicons: ^3.0.0
+  flutter_custom_toolbox:
+    git:
+      url: https://git.harrault.fr/android/flutter-toolbox.git
+      ref: 0.1.1
 
   # specific
   fl_chart: ^0.69.0
@@ -36,15 +31,3 @@ flutter:
   uses-material-design: true
   assets:
     - assets/translations/
-
-  fonts:
-    - family: Nunito
-      fonts:
-        - asset: assets/fonts/Nunito-Bold.ttf
-          weight: 700
-        - asset: assets/fonts/Nunito-Medium.ttf
-          weight: 500
-        - asset: assets/fonts/Nunito-Regular.ttf
-          weight: 400
-        - asset: assets/fonts/Nunito-Light.ttf
-          weight: 300