diff --git a/android/gradle.properties b/android/gradle.properties
index 7cc965a085f8a41bab04af9a3eb0a67ded5e75d9..1764beb0b9cf3403ae552dc187f308529a8d428e 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
 android.useAndroidX=true
 android.enableJetifier=true
-app.versionName=1.0.50
-app.versionCode=51
+app.versionName=1.0.51
+app.versionCode=52
diff --git a/assets/translations/en.json b/assets/translations/en.json
index 7280a8a3e1e7d0316800f5a1005c0893419ca4cd..4f597623aec94ec04f12bc1620c6d051dd96a9c1 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -12,6 +12,7 @@
   "api_page_title": "API",
 
   "settings_title": "Settings",
+  "settings_label_theme": "Theme mode",
   "settings_label_api_url": "API URL:",
   "settings_label_security_token": "Security token:",
   "settings_label_interface_type": "Interface type:",
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
index 5ef35e50be00a17d1c45e5deca1517d327ef6341..aa559e2d4280fe5b2fb4591bef9bac2a5db4843b 100644
--- a/assets/translations/fr.json
+++ b/assets/translations/fr.json
@@ -12,6 +12,7 @@
   "api_page_title": "API",
 
   "settings_title": "Paramètres",
+  "settings_label_theme": "Thème de couleurs",
   "settings_label_api_url": "URL de l'API :",
   "settings_label_security_token": "Jeton de sécurité :",
   "settings_label_interface_type": "Type d'interface :",
diff --git a/lib/config/menu.dart b/lib/config/menu.dart
index b06e9eb05c661cd00f4df9d6fd3675ba799f50ad..99f8668f54cc540b33e76d58e7b2d78f276ccdc2 100644
--- a/lib/config/menu.dart
+++ b/lib/config/menu.dart
@@ -62,7 +62,10 @@ class Menu {
   ];
 
   static Widget getPageWidget(int pageIndex) {
-    return Menu.items.elementAt(pageIndex).page;
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 8),
+      child: Menu.items.elementAt(pageIndex).page,
+    );
   }
 
   static List<BottomNavigationBarItem> getMenuItems() {
diff --git a/lib/cubit/theme_cubit.dart b/lib/cubit/theme_cubit.dart
new file mode 100644
index 0000000000000000000000000000000000000000..b793e895dbb0c672d451cd403e0036c3d9ac9b42
--- /dev/null
+++ b/lib/cubit/theme_cubit.dart
@@ -0,0 +1,31 @@
+import 'package:equatable/equatable.dart';
+import 'package:flutter/material.dart';
+import 'package:hydrated_bloc/hydrated_bloc.dart';
+
+part 'theme_state.dart';
+
+class ThemeCubit extends HydratedCubit<ThemeModeState> {
+  ThemeCubit() : super(const ThemeModeState());
+
+  void getTheme(ThemeModeState state) {
+    emit(state);
+  }
+
+  @override
+  ThemeModeState? fromJson(Map<String, dynamic> json) {
+    switch (json['themeMode']) {
+      case 'ThemeMode.dark':
+        return const ThemeModeState(themeMode: ThemeMode.dark);
+      case 'ThemeMode.light':
+        return const ThemeModeState(themeMode: ThemeMode.light);
+      case 'ThemeMode.system':
+      default:
+        return const ThemeModeState(themeMode: ThemeMode.system);
+    }
+  }
+
+  @override
+  Map<String, String>? toJson(ThemeModeState state) {
+    return <String, String>{'themeMode': state.themeMode.toString()};
+  }
+}
diff --git a/lib/cubit/theme_state.dart b/lib/cubit/theme_state.dart
new file mode 100644
index 0000000000000000000000000000000000000000..e479a50f12fe72a35a1fd1722ff72afbb692a136
--- /dev/null
+++ b/lib/cubit/theme_state.dart
@@ -0,0 +1,15 @@
+part of 'theme_cubit.dart';
+
+@immutable
+class ThemeModeState extends Equatable {
+  const ThemeModeState({
+    this.themeMode,
+  });
+
+  final ThemeMode? themeMode;
+
+  @override
+  List<Object?> get props => <Object?>[
+        themeMode,
+      ];
+}
diff --git a/lib/main.dart b/lib/main.dart
index ca105a76396f0950f7ed21c7aa7d29091f1bf3f6..b4a2c31cd3ff8f43041e32e164f696c875460e15 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -8,11 +8,12 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
 import 'package:path_provider/path_provider.dart';
 
 import 'package:random/config/theme.dart';
+import 'package:random/cubit/api_cubit.dart';
 import 'package:random/cubit/bottom_nav_cubit.dart';
 import 'package:random/cubit/data_cubit.dart';
 import 'package:random/cubit/game_cubit.dart';
 import 'package:random/cubit/settings_cubit.dart';
-import 'package:random/cubit/api_cubit.dart';
+import 'package:random/cubit/theme_cubit.dart';
 import 'package:random/repository/api.dart';
 import 'package:random/network/api.dart';
 import 'package:random/ui/skeleton.dart';
@@ -48,10 +49,6 @@ class MyApp extends StatelessWidget {
   Widget build(BuildContext context) {
     return MultiBlocProvider(
       providers: [
-        BlocProvider<SettingsCubit>(create: (context) => SettingsCubit()),
-        BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
-        BlocProvider<DataCubit>(create: (context) => DataCubit()),
-        BlocProvider<GameCubit>(create: (context) => GameCubit()),
         BlocProvider<ApiDataCubit>(
           create: (context) => ApiDataCubit(
             apiRepository: ApiRepository(
@@ -59,16 +56,26 @@ class MyApp extends StatelessWidget {
             ),
           )..fetchApiData(),
         ),
+        BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
+        BlocProvider<DataCubit>(create: (context) => DataCubit()),
+        BlocProvider<GameCubit>(create: (context) => GameCubit()),
+        BlocProvider<SettingsCubit>(create: (context) => SettingsCubit()),
+        BlocProvider<ThemeCubit>(create: (context) => ThemeCubit()),
       ],
-      child: MaterialApp(
-        title: 'Random application',
-        theme: appTheme,
-        home: const SkeletonScreen(),
-        localizationsDelegates: context.localizationDelegates,
-        supportedLocales: context.supportedLocales,
-        locale: context.locale,
-        debugShowCheckedModeBanner: false,
-      ),
+      child: BlocBuilder<ThemeCubit, ThemeModeState>(
+          builder: (BuildContext context, ThemeModeState state) {
+        return MaterialApp(
+          title: 'Random application',
+          theme: lightTheme,
+          darkTheme: darkTheme,
+          themeMode: state.themeMode,
+          home: const SkeletonScreen(),
+          localizationsDelegates: context.localizationDelegates,
+          supportedLocales: context.supportedLocales,
+          locale: context.locale,
+          debugShowCheckedModeBanner: false,
+        );
+      }),
     );
   }
 }
diff --git a/lib/ui/screens/game_page.dart b/lib/ui/screens/game_page.dart
index 1f845c855f69c09a9f7b4b5cc76bb824118be192..a0db19d0e8a1d181337c06523614a8f3d91cad00 100644
--- a/lib/ui/screens/game_page.dart
+++ b/lib/ui/screens/game_page.dart
@@ -25,7 +25,7 @@ class _GamePageState extends State<GamePage> {
             gameCubit.updateGameState(Game.createNew());
           },
           icon: const Icon(UniconsSolid.star),
-          color: Colors.white,
+          color: Theme.of(context).colorScheme.primary,
         )
       ];
 
@@ -39,7 +39,7 @@ class _GamePageState extends State<GamePage> {
             setState(() {});
           },
           icon: const Icon(UniconsLine.exit),
-          color: Colors.white,
+          color: Theme.of(context).colorScheme.primary,
         ));
       }
 
diff --git a/lib/ui/widgets/settings_form.dart b/lib/ui/widgets/settings_form.dart
index 5cd634890c1575097a977b15eb289560523745e8..facc79d4ad75a3d4e3840340a9be0f0fecd6df31 100644
--- a/lib/ui/widgets/settings_form.dart
+++ b/lib/ui/widgets/settings_form.dart
@@ -6,6 +6,7 @@ import 'package:unicons/unicons.dart';
 import 'package:random/cubit/settings_cubit.dart';
 import 'package:random/config/theme.dart';
 import 'package:random/models/interface_type.dart';
+import 'package:random/ui/widgets/theme_card.dart';
 
 class SettingsForm extends StatefulWidget {
   const SettingsForm({super.key});
@@ -54,6 +55,35 @@ class _SettingsFormState extends State<SettingsForm> {
       crossAxisAlignment: CrossAxisAlignment.start,
       mainAxisSize: MainAxisSize.max,
       children: <Widget>[
+        // Light/dark theme
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: <Widget>[
+            const Text('settings_label_theme').tr(),
+            const Row(
+              mainAxisAlignment: MainAxisAlignment.end,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                ThemeCard(
+                  mode: ThemeMode.system,
+                  icon: UniconsLine.cog,
+                ),
+                ThemeCard(
+                  mode: ThemeMode.light,
+                  icon: UniconsLine.sun,
+                ),
+                ThemeCard(
+                  mode: ThemeMode.dark,
+                  icon: UniconsLine.moon,
+                )
+              ],
+            ),
+          ],
+        ),
+
+        const SizedBox(height: 16),
+
         const Text('settings_label_api_url').tr(),
         TextFormField(
           controller: apiUrlController,
@@ -61,7 +91,9 @@ class _SettingsFormState extends State<SettingsForm> {
             border: UnderlineInputBorder(),
           ),
         ),
+
         const SizedBox(height: 16),
+
         const Text('settings_label_security_token').tr(),
         TextFormField(
           controller: securityTokenController,
@@ -69,7 +101,9 @@ class _SettingsFormState extends State<SettingsForm> {
             border: UnderlineInputBorder(),
           ),
         ),
+
         const SizedBox(height: 16),
+
         const Text('settings_label_interface_type').tr(),
         ToggleButtons(
           direction: Axis.horizontal,
diff --git a/lib/ui/widgets/theme_card.dart b/lib/ui/widgets/theme_card.dart
new file mode 100644
index 0000000000000000000000000000000000000000..e68441ca95c75152711027b36d7ed68bd71b5c40
--- /dev/null
+++ b/lib/ui/widgets/theme_card.dart
@@ -0,0 +1,45 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:random/cubit/theme_cubit.dart';
+
+class ThemeCard extends StatelessWidget {
+  const ThemeCard({
+    super.key,
+    required this.mode,
+    required this.icon,
+  });
+
+  final IconData icon;
+  final ThemeMode mode;
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<ThemeCubit, ThemeModeState>(
+        builder: (BuildContext context, ThemeModeState state) {
+      return Card(
+        elevation: 2,
+        shadowColor: Theme.of(context).colorScheme.shadow,
+        color: state.themeMode == mode
+            ? Theme.of(context).colorScheme.primary
+            : Theme.of(context).colorScheme.surface,
+        shape: const RoundedRectangleBorder(
+          borderRadius: BorderRadius.all(Radius.circular(12)),
+        ),
+        margin: const EdgeInsets.all(5),
+        child: InkWell(
+          onTap: () => BlocProvider.of<ThemeCubit>(context).getTheme(
+            ThemeModeState(themeMode: mode),
+          ),
+          borderRadius: const BorderRadius.all(Radius.circular(12)),
+          child: Icon(
+            icon,
+            size: 32,
+            color:
+                state.themeMode != mode ? Theme.of(context).colorScheme.primary : Colors.white,
+          ),
+        ),
+      );
+    });
+  }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 3de6bedec6d37ef273a3ca11a440ecc86dc249e0..38056a213177e3cb75e7f77fcd2c00ddb8160cc1 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: A random application, for testing purpose only.
 
 publish_to: 'none'
 
-version: 1.0.50+51
+version: 1.0.51+52
 
 environment:
   sdk: '^3.0.0'