diff --git a/android/gradle.properties b/android/gradle.properties
index 7ecc3f8ab655a592b129b0bcb8aaa8507c2a5be6..289e6accac51eee8a9ed1a90ef9a955c1958f120 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=0.1.38
-app.versionCode=62
+app.versionName=0.1.39
+app.versionCode=63
diff --git a/assets/fonts/Nunito-Bold.ttf b/assets/fonts/Nunito-Bold.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..6519feb781449ebe0015cbc74dfd9e13110fbba9
Binary files /dev/null and b/assets/fonts/Nunito-Bold.ttf differ
diff --git a/assets/fonts/Nunito-Light.ttf b/assets/fonts/Nunito-Light.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..8a0736c41cd6c2a1225d356bf274de1d0afc3497
Binary files /dev/null and b/assets/fonts/Nunito-Light.ttf differ
diff --git a/assets/fonts/Nunito-Medium.ttf b/assets/fonts/Nunito-Medium.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..88fccdc0638b6f5d6ac49d9d269dc3d518618ad1
Binary files /dev/null and b/assets/fonts/Nunito-Medium.ttf differ
diff --git a/assets/fonts/Nunito-Regular.ttf b/assets/fonts/Nunito-Regular.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..e7b8375a896ef0cd8e06730a78c84532b377e784
Binary files /dev/null and b/assets/fonts/Nunito-Regular.ttf differ
diff --git a/assets/translations/en.json b/assets/translations/en.json
new file mode 100644
index 0000000000000000000000000000000000000000..7a959c85f39256092adb9e8b230109e61283fb63
--- /dev/null
+++ b/assets/translations/en.json
@@ -0,0 +1,14 @@
+{
+  "app_name": "Word guess",
+
+  "bottom_nav_home": "Game",
+  "bottom_nav_settings": "Settings",
+  "bottom_nav_about": "About",
+
+  "settings_title": "Settings",
+  "settings_label_theme": "Theme mode",
+
+  "about_title": "About",
+  "about_content": "Word guess game.",
+  "about_version": "Version: {version}"
+}
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
new file mode 100644
index 0000000000000000000000000000000000000000..de1e73a173d57d55b362a6a9c92c6d5c88e4cd77
--- /dev/null
+++ b/assets/translations/fr.json
@@ -0,0 +1,14 @@
+{
+  "app_name": "Trouve le mot",
+
+  "bottom_nav_home": "Jeu",
+  "bottom_nav_settings": "Réglages",
+  "bottom_nav_about": "Infos",
+
+  "settings_title": "Réglages",
+  "settings_label_theme": "Thème de couleurs",
+
+  "about_title": "Informations",
+  "about_content": "Trouve le mot.",
+  "about_version": "Version : {version}"
+}
diff --git a/fastlane/metadata/android/en-US/changelogs/63.txt b/fastlane/metadata/android/en-US/changelogs/63.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6b884ec4ea3e942b988f5815114a1c3ab59810b8
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/63.txt
@@ -0,0 +1 @@
+Improve game conception/architecture.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/63.txt b/fastlane/metadata/android/fr-FR/changelogs/63.txt
new file mode 100644
index 0000000000000000000000000000000000000000..386b2cdcc090f19264599ba6dc6b215246489bce
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/63.txt
@@ -0,0 +1 @@
+Amélioration de la conception/architecture du jeu.
diff --git a/lib/config/menu.dart b/lib/config/menu.dart
new file mode 100644
index 0000000000000000000000000000000000000000..13081ea3b21b0c581d8dec4088186de0a98e3683
--- /dev/null
+++ b/lib/config/menu.dart
@@ -0,0 +1,54 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:unicons/unicons.dart';
+
+import 'package:wordguessing/ui/screens/about_page.dart';
+import 'package:wordguessing/ui/screens/game_page.dart';
+import 'package:wordguessing/ui/screens/settings_page.dart';
+
+class MenuItem {
+  final String code;
+  final Icon icon;
+  final Widget page;
+
+  const MenuItem({
+    required this.code,
+    required this.icon,
+    required this.page,
+  });
+}
+
+class Menu {
+  static List<MenuItem> items = [
+    const MenuItem(
+      code: 'bottom_nav_home',
+      icon: Icon(UniconsLine.home),
+      page: GamePage(),
+    ),
+    const MenuItem(
+      code: 'bottom_nav_settings',
+      icon: Icon(UniconsLine.setting),
+      page: SettingsPage(),
+    ),
+    const MenuItem(
+      code: 'bottom_nav_about',
+      icon: Icon(UniconsLine.info_circle),
+      page: AboutPage(),
+    ),
+  ];
+
+  static Widget getPageWidget(int pageIndex) {
+    return Menu.items.elementAt(pageIndex).page;
+  }
+
+  static List<BottomNavigationBarItem> getMenuItems() {
+    return Menu.items
+        .map((MenuItem item) => BottomNavigationBarItem(
+              icon: item.icon,
+              label: tr(item.code),
+            ))
+        .toList();
+  }
+
+  static int itemsCount = Menu.items.length;
+}
diff --git a/lib/config/theme.dart b/lib/config/theme.dart
new file mode 100644
index 0000000000000000000000000000000000000000..be390348c7868e7c63387df13e13c46de43f8a23
--- /dev/null
+++ b/lib/config/theme.dart
@@ -0,0 +1,196 @@
+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,
+  background: textSwatch.shade200,
+  onBackground: textSwatch.shade500,
+  onSurface: textSwatch.shade500,
+  surface: textSwatch.shade50,
+  surfaceVariant: Colors.white,
+  shadow: textSwatch.shade900.withOpacity(.1),
+);
+
+final ColorScheme darkColorScheme = ColorScheme.dark(
+  primary: primarySwatch.shade500,
+  secondary: primarySwatch.shade500,
+  onSecondary: Colors.white,
+  error: errorColor,
+  background: const Color(0xFF171724),
+  onBackground: textSwatch.shade400,
+  onSurface: textSwatch.shade300,
+  surface: const Color(0xFF262630),
+  surfaceVariant: 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/bottom_nav_cubit.dart b/lib/cubit/bottom_nav_cubit.dart
new file mode 100644
index 0000000000000000000000000000000000000000..96d5a6948ba1212c462227ef08403039b55e266d
--- /dev/null
+++ b/lib/cubit/bottom_nav_cubit.dart
@@ -0,0 +1,31 @@
+import 'package:hydrated_bloc/hydrated_bloc.dart';
+
+import 'package:wordguessing/config/menu.dart';
+
+class BottomNavCubit extends HydratedCubit<int> {
+  BottomNavCubit() : super(0);
+
+  void updateIndex(int index) {
+    if (isIndexAllowed(index)) {
+      emit(index);
+    } else {
+      goToHomePage();
+    }
+  }
+
+  bool isIndexAllowed(int index) {
+    return (index >= 0) && (index < Menu.itemsCount);
+  }
+
+  void goToHomePage() => emit(0);
+
+  @override
+  int fromJson(Map<String, dynamic> json) {
+    return 0;
+  }
+
+  @override
+  Map<String, dynamic>? toJson(int state) {
+    return <String, int>{'pageIndex': state};
+  }
+}
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 714a9fa8c3be7466ccdbc8941b1dfeb8878f250f..5dac5d3c52ce806d2155eae497dcae8f22810553 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,17 +1,41 @@
+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:provider/provider.dart';
 
+import 'package:wordguessing/config/theme.dart';
+import 'package:wordguessing/cubit/bottom_nav_cubit.dart';
+import 'package:wordguessing/cubit/theme_cubit.dart';
 import 'package:wordguessing/provider/data.dart';
-import 'package:wordguessing/screens/game_pick_image.dart';
-import 'package:wordguessing/screens/game_pick_word.dart';
-import 'package:wordguessing/screens/home.dart';
-import 'package:wordguessing/utils/tools.dart';
+import 'package:wordguessing/ui/skeleton.dart';
 
-void main() {
+void main() async {
+  /// Initialize packages
   WidgetsFlutterBinding.ensureInitialized();
-  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
-      .then((value) => runApp(const MyApp()));
+  await EasyLocalization.ensureInitialized();
+  final Directory tmpDir = await getTemporaryDirectory();
+  Hive.init(tmpDir.toString());
+  HydratedBloc.storage = await HydratedStorage.build(
+    storageDirectory: tmpDir,
+  );
+
+  runApp(
+    EasyLocalization(
+      path: 'assets/translations',
+      supportedLocales: const <Locale>[
+        Locale('en'),
+        Locale('fr'),
+      ],
+      fallbackLocale: const Locale('en'),
+      useFallbackTranslations: true,
+      child: const MyApp(),
+    ),
+  );
 }
 
 class MyApp extends StatelessWidget {
@@ -19,31 +43,34 @@ class MyApp extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return ChangeNotifierProvider(
-      create: (BuildContext context) => Data(),
-      child: Consumer<Data>(builder: (context, data, child) {
-        return MaterialApp(
-          title: 'Jeux de mots et lettres',
-          theme: ThemeData(
-            primarySwatch: Colors.blue,
+    return MultiBlocProvider(
+      providers: [
+        BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
+        BlocProvider<ThemeCubit>(create: (context) => ThemeCubit()),
+      ],
+      child: BlocBuilder<ThemeCubit, ThemeModeState>(
+          builder: (BuildContext context, ThemeModeState state) {
+        return ChangeNotifierProvider(
+          create: (BuildContext context) => Data(),
+          child: Consumer<Data>(
+            builder: (context, data, child) {
+              return MaterialApp(
+                title: 'Jeux de mots et lettres',
+                home: const SkeletonScreen(),
+
+                // Theme stuff
+                theme: lightTheme,
+                darkTheme: darkTheme,
+                themeMode: state.themeMode,
+
+                // Localization stuff
+                localizationsDelegates: context.localizationDelegates,
+                supportedLocales: context.supportedLocales,
+                locale: context.locale,
+                debugShowCheckedModeBanner: false,
+              );
+            },
           ),
-          home: const Home(),
-          onGenerateRoute: (settings) {
-            switch (settings.name) {
-              case '/game-pick-word':
-                return MaterialPageRoute(builder: (context) => const GamePickWordPage());
-
-              case '/game-pick-image':
-                return MaterialPageRoute(
-                  builder: (context) => const GamePickImagePage(),
-                );
-
-              default:
-                printlog("Unknown menu entry");
-            }
-
-            return null;
-          },
         );
       }),
     );
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
index c5559fd078007da84de91fcaab179530a81cc370..476ed718cdc77abe927802975ba9890cc9ff62a7 100644
--- a/lib/provider/data.dart
+++ b/lib/provider/data.dart
@@ -2,7 +2,11 @@ import 'package:flutter/foundation.dart';
 
 import 'package:wordguessing/models/word.dart';
 
+enum GameType { pickWord, pickImage }
+
 class Data extends ChangeNotifier {
+  GameType? _gameType;
+
   // Language
   String _lang = '';
 
@@ -18,6 +22,18 @@ class Data extends ChangeNotifier {
   int _goodAnswers = 0;
   int _wrongAnswers = 0;
 
+  GameType? get gameType => _gameType;
+
+  void updateGameType(GameType gameType) {
+    _gameType = gameType;
+    notifyListeners();
+  }
+
+  void resetGameType() {
+    _gameType = null;
+    notifyListeners();
+  }
+
   String get lang => _lang;
 
   void updateLang(String value) {
@@ -55,6 +71,7 @@ class Data extends ChangeNotifier {
   }
 
   void resetGame() {
+    resetGameType();
     updateLang('');
     updateQuestionsCount(0);
     updateGoodAnswers(0);
diff --git a/lib/screens/game.dart b/lib/ui/games/abstract_game.dart
similarity index 85%
rename from lib/screens/game.dart
rename to lib/ui/games/abstract_game.dart
index 00ede253129c7f06cc7a81bc1f796c9f24536b9f..6e25e32d90e0f2340aa2daaf187011a43aecb71d 100644
--- a/lib/screens/game.dart
+++ b/lib/ui/games/abstract_game.dart
@@ -3,13 +3,12 @@ import 'package:provider/provider.dart';
 
 import 'package:wordguessing/provider/data.dart';
 
-class Game extends StatelessWidget {
-  const Game({super.key});
+class GameAbstract extends StatelessWidget {
+  const GameAbstract({super.key});
 
   final int countWords = 4;
 
   Future<void> startGame(Data myProvider, String lang) async {
-    myProvider.resetGame();
     myProvider.updateLang(lang);
     await nextWord(myProvider);
   }
@@ -137,27 +136,6 @@ class Game extends StatelessWidget {
   Widget buildPage(BuildContext context) {
     final Data myProvider = Provider.of<Data>(context);
 
-    final Scaffold pageContent = Scaffold(
-      appBar: AppBar(
-        elevation: 0,
-        actions: <Widget>[
-          IconButton(
-            icon: const Icon(Icons.loop),
-            onPressed: () => myProvider.resetGame(),
-          ),
-        ],
-      ),
-      backgroundColor: Colors.blue,
-      body: Center(
-        child: Column(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          crossAxisAlignment: CrossAxisAlignment.center,
-          mainAxisSize: MainAxisSize.max,
-          children: buildPageContent(myProvider),
-        ),
-      ),
-    );
-
     return SizedBox.expand(
       child: FittedBox(
         fit: BoxFit.contain,
@@ -165,7 +143,14 @@ class Game extends StatelessWidget {
         child: SizedBox(
           height: (MediaQuery.of(context).size.height),
           width: (MediaQuery.of(context).size.width),
-          child: pageContent,
+          child: Center(
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisSize: MainAxisSize.max,
+              children: buildPageContent(myProvider),
+            ),
+          ),
         ),
       ),
     );
diff --git a/lib/screens/game_pick_image.dart b/lib/ui/games/game_pick_image.dart
similarity index 97%
rename from lib/screens/game_pick_image.dart
rename to lib/ui/games/game_pick_image.dart
index e0facc8cc34f1456f30de8656ad0ff37efbdd2dd..7f771c49dbca2b49fe295b292244a82156135955 100644
--- a/lib/screens/game_pick_image.dart
+++ b/lib/ui/games/game_pick_image.dart
@@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
 
 import 'package:wordguessing/models/word.dart';
 import 'package:wordguessing/provider/data.dart';
-import 'package:wordguessing/screens/game.dart';
+import 'package:wordguessing/ui/games/abstract_game.dart';
 import 'package:wordguessing/utils/random_pick_words.dart';
 
-class GamePickImagePage extends Game {
+class GamePickImagePage extends GameAbstract {
   const GamePickImagePage({super.key});
 
   @override
diff --git a/lib/screens/game_pick_word.dart b/lib/ui/games/game_pick_word.dart
similarity index 97%
rename from lib/screens/game_pick_word.dart
rename to lib/ui/games/game_pick_word.dart
index 86b842d69c214d7dcdbdcb8588f50f2f7b5d0fd1..d1b8b97bb330f41fceae6df9ee6e22b659e9f676 100644
--- a/lib/screens/game_pick_word.dart
+++ b/lib/ui/games/game_pick_word.dart
@@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
 
 import 'package:wordguessing/models/word.dart';
 import 'package:wordguessing/provider/data.dart';
-import 'package:wordguessing/screens/game.dart';
+import 'package:wordguessing/ui/games/abstract_game.dart';
 import 'package:wordguessing/utils/random_pick_words.dart';
 
-class GamePickWordPage extends Game {
+class GamePickWordPage extends GameAbstract {
   const GamePickWordPage({super.key});
 
   @override
diff --git a/lib/screens/home.dart b/lib/ui/games/game_selector.dart
similarity index 51%
rename from lib/screens/home.dart
rename to lib/ui/games/game_selector.dart
index e83989992c5d71837bebd95d617b4052e1a3558a..882d9521f02c8d42368f1b51d34456b50465ff6a 100644
--- a/lib/screens/home.dart
+++ b/lib/ui/games/game_selector.dart
@@ -3,16 +3,14 @@ import 'package:provider/provider.dart';
 
 import 'package:wordguessing/provider/data.dart';
 
-class Home extends StatelessWidget {
-  const Home({super.key});
-
-  static const String id = 'home';
+class GameSelector extends StatelessWidget {
+  const GameSelector({super.key});
 
   @override
   Widget build(BuildContext context) {
     final Data myProvider = Provider.of<Data>(context);
 
-    Container buildMenuItemContainer(String code, Color color) {
+    Widget buildMenuItemContainer(String code, Color color) {
       const double imageSize = 150;
 
       final String imageAsset = 'assets/menu/$code.png';
@@ -35,28 +33,32 @@ class Home extends StatelessWidget {
           ),
           onTap: () {
             myProvider.resetGame();
-            Navigator.pushNamed(
-              context,
-              '/$code',
-            );
+            switch (code) {
+              case 'game-pick-word':
+                myProvider.updateGameType(GameType.pickWord);
+                break;
+              case 'game-pick-image':
+                myProvider.updateGameType(GameType.pickImage);
+                break;
+              default:
+            }
           },
         ),
       );
     }
 
-    return Scaffold(
-      backgroundColor: Colors.blue,
-      body: Center(
-        child: Column(
-          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
-          crossAxisAlignment: CrossAxisAlignment.center,
-          mainAxisSize: MainAxisSize.max,
-          children: <Widget>[
-            buildMenuItemContainer('game-pick-word', Colors.pink),
-            buildMenuItemContainer('game-pick-image', Colors.yellow),
-          ],
-        ),
+    Widget content = Center(
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+        crossAxisAlignment: CrossAxisAlignment.center,
+        mainAxisSize: MainAxisSize.max,
+        children: <Widget>[
+          buildMenuItemContainer('game-pick-word', Colors.pink),
+          buildMenuItemContainer('game-pick-image', Colors.yellow),
+        ],
       ),
     );
+
+    return content;
   }
 }
diff --git a/lib/ui/screens/about_page.dart b/lib/ui/screens/about_page.dart
new file mode 100644
index 0000000000000000000000000000000000000000..05d19322774be26931233ecd40beb1adffe27b55
--- /dev/null
+++ b/lib/ui/screens/about_page.dart
@@ -0,0 +1,41 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+
+import 'package:wordguessing/ui/widgets/header_app.dart';
+
+class AboutPage extends StatelessWidget {
+  const AboutPage({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 8),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisSize: MainAxisSize.max,
+        children: <Widget>[
+          const SizedBox(height: 8),
+          const AppHeader(text: 'about_title'),
+          const Text('about_content').tr(),
+          FutureBuilder<PackageInfo>(
+            future: PackageInfo.fromPlatform(),
+            builder: (context, snapshot) {
+              switch (snapshot.connectionState) {
+                case ConnectionState.done:
+                  return const Text('about_version').tr(
+                    namedArgs: {
+                      'version': snapshot.data!.version,
+                    },
+                  );
+                default:
+                  return const SizedBox();
+              }
+            },
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/ui/screens/game_page.dart b/lib/ui/screens/game_page.dart
new file mode 100644
index 0000000000000000000000000000000000000000..df3c84376e9d37a3040d09e0665f19d3abca2165
--- /dev/null
+++ b/lib/ui/screens/game_page.dart
@@ -0,0 +1,25 @@
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+import 'package:wordguessing/provider/data.dart';
+import 'package:wordguessing/ui/games/game_pick_image.dart';
+import 'package:wordguessing/ui/games/game_pick_word.dart';
+import 'package:wordguessing/ui/games/game_selector.dart';
+
+class GamePage extends StatelessWidget {
+  const GamePage({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    final Data myProvider = Provider.of<Data>(context);
+
+    switch (myProvider.gameType) {
+      case GameType.pickImage:
+        return const GamePickImagePage();
+      case GameType.pickWord:
+        return const GamePickWordPage();
+      default:
+        return const GameSelector();
+    }
+  }
+}
diff --git a/lib/ui/screens/settings_page.dart b/lib/ui/screens/settings_page.dart
new file mode 100644
index 0000000000000000000000000000000000000000..df50c147d84f6b0b8358bdc18fc6898cadefc1fb
--- /dev/null
+++ b/lib/ui/screens/settings_page.dart
@@ -0,0 +1,26 @@
+import 'package:flutter/material.dart';
+
+import 'package:wordguessing/ui/widgets/header_app.dart';
+import 'package:wordguessing/ui/widgets/settings/settings_form.dart';
+
+class SettingsPage extends StatelessWidget {
+  const SettingsPage({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const Padding(
+      padding: EdgeInsets.symmetric(horizontal: 8),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisSize: MainAxisSize.max,
+        children: <Widget>[
+          SizedBox(height: 8),
+          AppHeader(text: 'settings_title'),
+          SizedBox(height: 8),
+          SettingsForm(),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
new file mode 100644
index 0000000000000000000000000000000000000000..bc0a8a0bffaf7382bcf8473fd6ecfd12aff9b37a
--- /dev/null
+++ b/lib/ui/skeleton.dart
@@ -0,0 +1,49 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_swipe/flutter_swipe.dart';
+import 'package:provider/provider.dart';
+
+import 'package:wordguessing/config/menu.dart';
+import 'package:wordguessing/cubit/bottom_nav_cubit.dart';
+import 'package:wordguessing/provider/data.dart';
+import 'package:wordguessing/ui/widgets/app_bar.dart';
+import 'package:wordguessing/ui/widgets/bottom_nav_bar.dart';
+
+class SkeletonScreen extends StatefulWidget {
+  const SkeletonScreen({super.key});
+
+  @override
+  State<SkeletonScreen> createState() => _SkeletonScreenState();
+}
+
+class _SkeletonScreenState extends State<SkeletonScreen> {
+  @override
+  Widget build(BuildContext context) {
+    final Data myProvider = Provider.of<Data>(context);
+
+    return Scaffold(
+      extendBodyBehindAppBar: false,
+      appBar: StandardAppBar(myProvider: myProvider),
+      body: Swiper(
+        itemCount: Menu.itemsCount,
+        itemBuilder: (BuildContext context, int index) {
+          return Menu.getPageWidget(index);
+        },
+        pagination: SwiperPagination(
+          margin: const EdgeInsets.all(0),
+          builder: SwiperCustomPagination(
+            builder: (BuildContext context, SwiperPluginConfig config) {
+              return BottomNavBar(swipeController: config.controller);
+            },
+          ),
+        ),
+        onIndexChanged: (newPageIndex) {
+          BlocProvider.of<BottomNavCubit>(context).updateIndex(newPageIndex);
+        },
+        outer: true,
+        loop: false,
+      ),
+      backgroundColor: Theme.of(context).colorScheme.background,
+    );
+  }
+}
diff --git a/lib/ui/widgets/app_bar.dart b/lib/ui/widgets/app_bar.dart
new file mode 100644
index 0000000000000000000000000000000000000000..73038ecffd02c00b457707a647a0b9b57ebdaa3f
--- /dev/null
+++ b/lib/ui/widgets/app_bar.dart
@@ -0,0 +1,32 @@
+import 'package:flutter/material.dart';
+
+import 'package:wordguessing/provider/data.dart';
+import 'package:wordguessing/ui/widgets/header_app.dart';
+
+class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
+  const StandardAppBar({super.key, required this.myProvider});
+
+  final Data myProvider;
+
+  @override
+  Widget build(BuildContext context) {
+    final List<Widget> menuActions = [];
+
+    if (myProvider.gameType != null) {
+      menuActions.add(
+        IconButton(
+          icon: const Icon(Icons.loop),
+          onPressed: () => myProvider.resetGame(),
+        ),
+      );
+    }
+
+    return AppBar(
+      title: const AppHeader(text: 'app_name'),
+      actions: menuActions,
+    );
+  }
+
+  @override
+  Size get preferredSize => const Size.fromHeight(50);
+}
diff --git a/lib/ui/widgets/bottom_nav_bar.dart b/lib/ui/widgets/bottom_nav_bar.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4e1d708cac14eb145f0934a92f552782d72ca978
--- /dev/null
+++ b/lib/ui/widgets/bottom_nav_bar.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_swipe/flutter_swipe.dart';
+
+import 'package:wordguessing/config/menu.dart';
+import 'package:wordguessing/cubit/bottom_nav_cubit.dart';
+
+class BottomNavBar extends StatelessWidget {
+  const BottomNavBar({super.key, required this.swipeController});
+
+  final SwiperController swipeController;
+
+  @override
+  Widget build(BuildContext context) {
+    return Card(
+      margin: const EdgeInsets.all(0),
+      elevation: 4,
+      shadowColor: Theme.of(context).colorScheme.shadow,
+      color: Theme.of(context).colorScheme.surfaceVariant,
+      shape: const ContinuousRectangleBorder(),
+      child: BlocBuilder<BottomNavCubit, int>(
+        builder: (BuildContext context, int state) {
+          return BottomNavigationBar(
+            currentIndex: state,
+            onTap: (int index) {
+              context.read<BottomNavCubit>().updateIndex(index);
+              swipeController.move(index);
+            },
+            type: BottomNavigationBarType.fixed,
+            elevation: 0,
+            backgroundColor: Colors.transparent,
+            selectedItemColor: Theme.of(context).colorScheme.primary,
+            unselectedItemColor: Theme.of(context).textTheme.bodySmall!.color,
+            items: Menu.getMenuItems(),
+          );
+        },
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/header_app.dart b/lib/ui/widgets/header_app.dart
new file mode 100644
index 0000000000000000000000000000000000000000..bf54b77375fbd0260f876f2885d0572b71715383
--- /dev/null
+++ b/lib/ui/widgets/header_app.dart
@@ -0,0 +1,23 @@
+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 Row(
+      mainAxisAlignment: MainAxisAlignment.start,
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Text(
+          tr(text),
+          textAlign: TextAlign.start,
+          style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
+        ),
+      ],
+    );
+  }
+}
diff --git a/lib/ui/widgets/settings/settings_form.dart b/lib/ui/widgets/settings/settings_form.dart
new file mode 100644
index 0000000000000000000000000000000000000000..cb59277121264dace76f59d41290687c575f3a4f
--- /dev/null
+++ b/lib/ui/widgets/settings/settings_form.dart
@@ -0,0 +1,63 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:unicons/unicons.dart';
+
+import 'package:wordguessing/ui/widgets/settings/theme_card.dart';
+
+class SettingsForm extends StatefulWidget {
+  const SettingsForm({super.key});
+
+  @override
+  State<SettingsForm> createState() => _SettingsFormState();
+}
+
+class _SettingsFormState extends State<SettingsForm> {
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      mainAxisAlignment: MainAxisAlignment.start,
+      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),
+      ],
+    );
+  }
+}
diff --git a/lib/ui/widgets/settings/theme_card.dart b/lib/ui/widgets/settings/theme_card.dart
new file mode 100644
index 0000000000000000000000000000000000000000..bd1b3ab5b0ee216d3836ec8ba19a30181f65be23
--- /dev/null
+++ b/lib/ui/widgets/settings/theme_card.dart
@@ -0,0 +1,47 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:wordguessing/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.lock b/pubspec.lock
index b15ebfbb8fc4b11d61a5733db2b95e116d18c681..53bc85dec4bae56188e56f74edcd0c91e60c1f18 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1,6 +1,30 @@
 # Generated by pub
 # See https://dart.dev/tools/pub/glossary#lockfile
 packages:
+  args:
+    dependency: transitive
+    description:
+      name: args
+      sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.2"
+  async:
+    dependency: transitive
+    description:
+      name: async
+      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.11.0"
+  bloc:
+    dependency: transitive
+    description:
+      name: bloc
+      sha256: f53a110e3b48dcd78136c10daa5d51512443cea5e1348c9d80a320095fa2db9e
+      url: "https://pub.dev"
+    source: hosted
+    version: "8.1.3"
   characters:
     dependency: transitive
     description:
@@ -9,6 +33,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.0"
+  clock:
+    dependency: transitive
+    description:
+      name: clock
+      sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.1"
   collection:
     dependency: transitive
     description:
@@ -17,11 +49,67 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.18.0"
+  crypto:
+    dependency: transitive
+    description:
+      name: crypto
+      sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.3"
+  easy_localization:
+    dependency: "direct main"
+    description:
+      name: easy_localization
+      sha256: c145aeb6584aedc7c862ab8c737c3277788f47488bfdf9bae0fe112bd0a4789c
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.0.5"
+  easy_logger:
+    dependency: transitive
+    description:
+      name: easy_logger
+      sha256: c764a6e024846f33405a2342caf91c62e357c24b02c04dbc712ef232bf30ffb7
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.0.2"
+  equatable:
+    dependency: "direct main"
+    description:
+      name: equatable
+      sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.5"
+  ffi:
+    dependency: transitive
+    description:
+      name: ffi
+      sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.2"
+  file:
+    dependency: transitive
+    description:
+      name: file
+      sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "7.0.0"
   flutter:
     dependency: "direct main"
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_bloc:
+    dependency: "direct main"
+    description:
+      name: flutter_bloc
+      sha256: "87325da1ac757fcc4813e6b34ed5dd61169973871fdf181d6c2109dd6935ece1"
+      url: "https://pub.dev"
+    source: hosted
+    version: "8.1.4"
   flutter_lints:
     dependency: "direct dev"
     description:
@@ -30,6 +118,64 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.1"
+  flutter_localizations:
+    dependency: transitive
+    description: flutter
+    source: sdk
+    version: "0.0.0"
+  flutter_swipe:
+    dependency: "direct main"
+    description:
+      name: flutter_swipe
+      sha256: dc6541bac3a0545ce15a3fa15913f6250532062960bf6b0ad4562d02f14a8545
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.1"
+  flutter_web_plugins:
+    dependency: transitive
+    description: flutter
+    source: sdk
+    version: "0.0.0"
+  hive:
+    dependency: "direct main"
+    description:
+      name: hive
+      sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.3"
+  http:
+    dependency: transitive
+    description:
+      name: http
+      sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.0"
+  http_parser:
+    dependency: transitive
+    description:
+      name: http_parser
+      sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.0.2"
+  hydrated_bloc:
+    dependency: "direct main"
+    description:
+      name: hydrated_bloc
+      sha256: "00a2099680162e74b5a836b8a7f446e478520a9cae9f6032e028ad8129f4432d"
+      url: "https://pub.dev"
+    source: hosted
+    version: "9.1.4"
+  intl:
+    dependency: transitive
+    description:
+      name: intl
+      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.18.1"
   lints:
     dependency: transitive
     description:
@@ -62,6 +208,94 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.0"
+  package_info_plus:
+    dependency: "direct main"
+    description:
+      name: package_info_plus
+      sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79"
+      url: "https://pub.dev"
+    source: hosted
+    version: "5.0.1"
+  package_info_plus_platform_interface:
+    dependency: transitive
+    description:
+      name: package_info_plus_platform_interface
+      sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.1"
+  path:
+    dependency: "direct main"
+    description:
+      name: path
+      sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.9.0"
+  path_provider:
+    dependency: "direct main"
+    description:
+      name: path_provider
+      sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.2"
+  path_provider_android:
+    dependency: transitive
+    description:
+      name: path_provider_android
+      sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.2"
+  path_provider_foundation:
+    dependency: transitive
+    description:
+      name: path_provider_foundation
+      sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.2"
+  path_provider_linux:
+    dependency: transitive
+    description:
+      name: path_provider_linux
+      sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.1"
+  path_provider_platform_interface:
+    dependency: transitive
+    description:
+      name: path_provider_platform_interface
+      sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.2"
+  path_provider_windows:
+    dependency: transitive
+    description:
+      name: path_provider_windows
+      sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.1"
+  platform:
+    dependency: transitive
+    description:
+      name: platform
+      sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.4"
+  plugin_platform_interface:
+    dependency: transitive
+    description:
+      name: plugin_platform_interface
+      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.8"
   provider:
     dependency: "direct main"
     description:
@@ -70,11 +304,115 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "6.1.2"
+  shared_preferences:
+    dependency: transitive
+    description:
+      name: shared_preferences
+      sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.2"
+  shared_preferences_android:
+    dependency: transitive
+    description:
+      name: shared_preferences_android
+      sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.1"
+  shared_preferences_foundation:
+    dependency: transitive
+    description:
+      name: shared_preferences_foundation
+      sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.5"
+  shared_preferences_linux:
+    dependency: transitive
+    description:
+      name: shared_preferences_linux
+      sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.2"
+  shared_preferences_platform_interface:
+    dependency: transitive
+    description:
+      name: shared_preferences_platform_interface
+      sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.2"
+  shared_preferences_web:
+    dependency: transitive
+    description:
+      name: shared_preferences_web
+      sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.2"
+  shared_preferences_windows:
+    dependency: transitive
+    description:
+      name: shared_preferences_windows
+      sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.3.2"
   sky_engine:
     dependency: transitive
     description: flutter
     source: sdk
     version: "0.0.99"
+  source_span:
+    dependency: transitive
+    description:
+      name: source_span
+      sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.10.0"
+  string_scanner:
+    dependency: transitive
+    description:
+      name: string_scanner
+      sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.0"
+  synchronized:
+    dependency: transitive
+    description:
+      name: synchronized
+      sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.0+1"
+  term_glyph:
+    dependency: transitive
+    description:
+      name: term_glyph
+      sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.2.1"
+  typed_data:
+    dependency: transitive
+    description:
+      name: typed_data
+      sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.3.2"
+  unicons:
+    dependency: "direct main"
+    description:
+      name: unicons
+      sha256: dbfcf93ff4d4ea19b324113857e358e4882115ab85db04417a4ba1c72b17a670
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.1.1"
   vector_math:
     dependency: transitive
     description:
@@ -83,6 +421,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.4"
+  web:
+    dependency: transitive
+    description:
+      name: web
+      sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.4.2"
+  win32:
+    dependency: transitive
+    description:
+      name: win32
+      sha256: "8cb58b45c47dcb42ab3651533626161d6b67a2921917d8d429791f76972b3480"
+      url: "https://pub.dev"
+    source: hosted
+    version: "5.3.0"
+  xdg_directories:
+    dependency: transitive
+    description:
+      name: xdg_directories
+      sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.0.4"
 sdks:
-  dart: ">=3.2.0-0 <4.0.0"
-  flutter: ">=1.16.0"
+  dart: ">=3.3.0 <4.0.0"
+  flutter: ">=3.16.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index d97773d8549a68b6695843437dfe67c271281f9e..1deb1bf984aa492cbcf2fca016208c6d39d134c8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,8 @@
 name: wordguessing
 description: A wordguessing game application.
+
 publish_to: 'none'
-version: 0.1.38+62
+version: 0.1.39+63
 
 environment:
   sdk: '^3.0.0'
@@ -9,7 +10,18 @@ environment:
 dependencies:
   flutter:
     sdk: flutter
+
+  easy_localization: ^3.0.1
+  equatable: ^2.0.5
+  flutter_bloc: ^8.1.1
+  flutter_swipe: ^1.0.1
+  hive: ^2.2.3
+  hydrated_bloc: ^9.0.0
+  package_info_plus: ^5.0.1
+  path: ^1.9.0
+  path_provider: ^2.0.11
   provider: ^6.0.5
+  unicons: ^2.1.1
 
 dev_dependencies:
   flutter_lints: ^3.0.1
@@ -21,3 +33,17 @@ flutter:
     - assets/images/
     - assets/menu/
     - assets/placeholder.png
+    - 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
+