diff --git a/assets/translations/en.json b/assets/translations/en.json
index 698056d0c6bd17e64befc5e4dd18f66b7fd912a9..e680e83b06768f8ec921f9761cb4b33c84db73a3 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -1,6 +1,9 @@
 {
   "app_name": "Sudoku",
 
+  "page_home": "Home",
+  "page_game": "Game",
+
   "settings_title": "Settings",
   "settings_label_theme": "Theme mode",
 
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
index 7d1f4e88ae2547e146ee1cc47e4394fd1ca71100..1cfd7150235c63a9319af1c6e41bb8f56353c9b4 100644
--- a/assets/translations/fr.json
+++ b/assets/translations/fr.json
@@ -1,6 +1,9 @@
 {
   "app_name": "Sudoku",
 
+  "page_home": "Accueil",
+  "page_game": "Jeu",
+
   "settings_title": "Réglages",
   "settings_label_theme": "Thème de couleurs",
 
diff --git a/fastlane/metadata/android/en-US/changelogs/78.txt b/fastlane/metadata/android/en-US/changelogs/78.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ac2c90e221caf3cf01ebba168fb16a8f31c0253a
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/78.txt
@@ -0,0 +1 @@
+Normalize Activity application architecture.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/78.txt b/fastlane/metadata/android/fr-FR/changelogs/78.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1d6843d89ba84ea4147528bc3d62d9ecf1a4a762
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/78.txt
@@ -0,0 +1 @@
+Harmonisation des applications en Activity.
diff --git a/lib/common/config/activity_page.dart b/lib/common/config/activity_page.dart
new file mode 100644
index 0000000000000000000000000000000000000000..d23e48899009701926dc7745ded3478e289b0f18
--- /dev/null
+++ b/lib/common/config/activity_page.dart
@@ -0,0 +1,50 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/common/ui/pages/game.dart';
+import 'package:sudoku/common/ui/pages/parameters.dart';
+
+class ActivityPageItem {
+  final String code;
+  final Icon icon;
+  final Widget page;
+
+  const ActivityPageItem({
+    required this.code,
+    required this.icon,
+    required this.page,
+  });
+}
+
+class ActivityPage {
+  static const bool displayBottomNavBar = false;
+
+  static const indexHome = 0;
+  static const pageHome = ActivityPageItem(
+    code: 'page_home',
+    icon: Icon(UniconsLine.home),
+    page: PageParameters(),
+  );
+
+  static const indexGame = 1;
+  static const pageGame = ActivityPageItem(
+    code: 'page_game',
+    icon: Icon(UniconsLine.star),
+    page: PageGame(),
+  );
+
+  static const Map<int, ActivityPageItem> items = {
+    indexHome: pageHome,
+    indexGame: pageGame,
+  };
+
+  static int defaultPageIndex = indexHome;
+
+  static bool isIndexAllowed(int pageIndex) {
+    return items.keys.contains(pageIndex);
+  }
+
+  static Widget getWidget(int pageIndex) {
+    return items[pageIndex]?.page ?? pageHome.page;
+  }
+}
diff --git a/lib/common/config/screen.dart b/lib/common/config/screen.dart
new file mode 100644
index 0000000000000000000000000000000000000000..fdbcaa3bcde75bda1ed1860ae3cb826e1e847493
--- /dev/null
+++ b/lib/common/config/screen.dart
@@ -0,0 +1,55 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/common/ui/screens/about.dart';
+import 'package:sudoku/common/ui/screens/activity.dart';
+import 'package:sudoku/common/ui/screens/settings.dart';
+
+class ScreenItem {
+  final String code;
+  final Icon icon;
+  final Widget screen;
+
+  const ScreenItem({
+    required this.code,
+    required this.icon,
+    required this.screen,
+  });
+}
+
+class Screen {
+  static const indexActivity = 0;
+  static const screenActivity = ScreenItem(
+    code: 'screen_activity',
+    icon: Icon(UniconsLine.home),
+    screen: ScreenActivity(),
+  );
+
+  static const indexSettings = 1;
+  static const screenSettings = ScreenItem(
+    code: 'screen_settings',
+    icon: Icon(UniconsLine.setting),
+    screen: ScreenSettings(),
+  );
+
+  static const indexAbout = 2;
+  static const screenAbout = ScreenItem(
+    code: 'screen_about',
+    icon: Icon(UniconsLine.info_circle),
+    screen: ScreenAbout(),
+  );
+
+  static Map<int, ScreenItem> items = {
+    indexActivity: screenActivity,
+    indexSettings: screenSettings,
+    indexAbout: screenAbout,
+  };
+
+  static bool isIndexAllowed(int screenIndex) {
+    return items.keys.contains(screenIndex);
+  }
+
+  static Widget getWidget(int screenIndex) {
+    return items[screenIndex]?.screen ?? screenActivity.screen;
+  }
+}
diff --git a/lib/common/cubit/nav/nav_cubit_pages.dart b/lib/common/cubit/nav/nav_cubit_pages.dart
new file mode 100644
index 0000000000000000000000000000000000000000..b185e89310fc976143c1291899aa09545ee672e6
--- /dev/null
+++ b/lib/common/cubit/nav/nav_cubit_pages.dart
@@ -0,0 +1,33 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/common/config/activity_page.dart';
+
+class NavCubitPage extends HydratedCubit<int> {
+  NavCubitPage() : super(0);
+
+  void updateIndex(int index) {
+    if (ActivityPage.isIndexAllowed(index)) {
+      emit(index);
+    } else {
+      emit(ActivityPage.indexHome);
+    }
+  }
+
+  void goToPageHome() {
+    updateIndex(ActivityPage.indexHome);
+  }
+
+  void goToPageGame() {
+    updateIndex(ActivityPage.indexGame);
+  }
+
+  @override
+  int fromJson(Map<String, dynamic> json) {
+    return ActivityPage.indexHome;
+  }
+
+  @override
+  Map<String, dynamic>? toJson(int state) {
+    return <String, int>{'index': state};
+  }
+}
diff --git a/lib/common/cubit/nav/nav_cubit_screens.dart b/lib/common/cubit/nav/nav_cubit_screens.dart
new file mode 100644
index 0000000000000000000000000000000000000000..f30c0f15798e3153b6674df37c423d5e73bbe768
--- /dev/null
+++ b/lib/common/cubit/nav/nav_cubit_screens.dart
@@ -0,0 +1,37 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/common/config/screen.dart';
+
+class NavCubitScreen extends HydratedCubit<int> {
+  NavCubitScreen() : super(0);
+
+  void updateIndex(int index) {
+    if (Screen.isIndexAllowed(index)) {
+      emit(index);
+    } else {
+      goToScreenActivity();
+    }
+  }
+
+  void goToScreenActivity() {
+    emit(Screen.indexActivity);
+  }
+
+  void goToScreenSettings() {
+    emit(Screen.indexSettings);
+  }
+
+  void goToScreenAbout() {
+    emit(Screen.indexAbout);
+  }
+
+  @override
+  int fromJson(Map<String, dynamic> json) {
+    return Screen.indexActivity;
+  }
+
+  @override
+  Map<String, dynamic>? toJson(int state) {
+    return <String, int>{'index': state};
+  }
+}
diff --git a/lib/common/ui/nav/bottom_nav_bar.dart b/lib/common/ui/nav/bottom_nav_bar.dart
new file mode 100644
index 0000000000000000000000000000000000000000..9429470d70d102a79071e3b1fab238e7e8559c5c
--- /dev/null
+++ b/lib/common/ui/nav/bottom_nav_bar.dart
@@ -0,0 +1,46 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/common/config/activity_page.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_pages.dart';
+
+class BottomNavBar extends StatelessWidget {
+  const BottomNavBar({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Card(
+      margin: const EdgeInsets.only(top: 1, right: 4, left: 4),
+      elevation: 4,
+      shadowColor: Theme.of(context).colorScheme.shadow,
+      color: Theme.of(context).colorScheme.surfaceContainerHighest,
+      shape: const RoundedRectangleBorder(
+        borderRadius: BorderRadius.only(
+          topLeft: Radius.circular(16),
+          topRight: Radius.circular(16),
+        ),
+      ),
+      child: BlocBuilder<NavCubitPage, int>(builder: (BuildContext context, int state) {
+        final List<BottomNavigationBarItem> items = [];
+
+        ActivityPage.items.forEach((int pageIndex, ActivityPageItem item) {
+          items.add(BottomNavigationBarItem(
+            icon: item.icon,
+            label: tr(item.code),
+          ));
+        });
+
+        return BottomNavigationBar(
+          currentIndex: state,
+          onTap: (int index) => BlocProvider.of<NavCubitPage>(context).updateIndex(index),
+          type: BottomNavigationBarType.fixed,
+          elevation: 0,
+          backgroundColor: Colors.transparent,
+          selectedItemColor: Theme.of(context).colorScheme.primary,
+          unselectedItemColor: Theme.of(context).textTheme.bodySmall!.color,
+          items: items,
+        );
+      }),
+    );
+  }
+}
diff --git a/lib/ui/widgets/global_app_bar.dart b/lib/common/ui/nav/global_app_bar.dart
similarity index 61%
rename from lib/ui/widgets/global_app_bar.dart
rename to lib/common/ui/nav/global_app_bar.dart
index d7b499bf0abe773ada40004a7a74ea9edb3ecc2d..bfe92eb18fcdbf04bff136be61763db7b256f214 100644
--- a/lib/ui/widgets/global_app_bar.dart
+++ b/lib/common/ui/nav/global_app_bar.dart
@@ -1,30 +1,33 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/config/menu.dart';
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/cubit/nav_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/common/config/screen.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_pages.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_screens.dart';
+
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
 
 class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
   const GlobalAppBar({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        return BlocBuilder<NavCubit, int>(
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        return BlocBuilder<NavCubitScreen, int>(
           builder: (BuildContext context, int pageIndex) {
-            final Game currentGame = gameState.currentGame;
+            final Activity currentActivity = activityState.currentActivity;
 
             final List<Widget> menuActions = [];
 
-            if (currentGame.isRunning && !currentGame.isFinished) {
+            if (currentActivity.isRunning && !currentActivity.isFinished) {
               menuActions.add(StyledButton(
                 color: Colors.red,
                 onPressed: () {},
                 onLongPress: () {
-                  BlocProvider.of<GameCubit>(context).quitGame();
+                  BlocProvider.of<ActivityCubit>(context).quitActivity();
+                  BlocProvider.of<NavCubitPage>(context).goToPageHome();
                 },
                 child: const Image(
                   image: AssetImage('assets/ui/button_back.png'),
@@ -33,38 +36,38 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
               ));
               menuActions.add(const Spacer(flex: 6));
             } else {
-              if (pageIndex == Menu.indexGame) {
+              if (pageIndex == Screen.indexActivity) {
                 // go to Settings page
                 menuActions.add(ElevatedButton(
                   onPressed: () {
-                    BlocProvider.of<NavCubit>(context).goToSettingsPage();
+                    BlocProvider.of<NavCubitScreen>(context).goToScreenSettings();
                   },
                   style: ElevatedButton.styleFrom(
                     shape: const CircleBorder(),
                   ),
-                  child: Menu.menuItemSettings.icon,
+                  child: Screen.screenSettings.icon,
                 ));
 
                 // go to About page
                 menuActions.add(ElevatedButton(
                   onPressed: () {
-                    BlocProvider.of<NavCubit>(context).goToAboutPage();
+                    BlocProvider.of<NavCubitScreen>(context).goToScreenAbout();
                   },
                   style: ElevatedButton.styleFrom(
                     shape: const CircleBorder(),
                   ),
-                  child: Menu.menuItemAbout.icon,
+                  child: Screen.screenAbout.icon,
                 ));
               } else {
                 // back to Home page
                 menuActions.add(ElevatedButton(
                   onPressed: () {
-                    BlocProvider.of<NavCubit>(context).goToGamePage();
+                    BlocProvider.of<NavCubitScreen>(context).goToScreenActivity();
                   },
                   style: ElevatedButton.styleFrom(
                     shape: const CircleBorder(),
                   ),
-                  child: Menu.menuItemGame.icon,
+                  child: Screen.screenActivity.icon,
                 ));
               }
             }
diff --git a/lib/ui/layouts/game_layout.dart b/lib/common/ui/pages/game.dart
similarity index 66%
rename from lib/ui/layouts/game_layout.dart
rename to lib/common/ui/pages/game.dart
index 0798d0b8cca614dfb7b8036c91585c15efd46950..e66453d5fe0faa69c779be200937c4f9f4e7bb45 100644
--- a/lib/ui/layouts/game_layout.dart
+++ b/lib/common/ui/pages/game.dart
@@ -1,21 +1,21 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
 import 'package:sudoku/ui/game/game_bottom.dart';
 import 'package:sudoku/ui/game/game_end.dart';
 import 'package:sudoku/ui/game/game_top.dart';
 import 'package:sudoku/ui/widgets/game/game_board.dart';
 
-class GameLayout extends StatelessWidget {
-  const GameLayout({super.key});
+class PageGame extends StatelessWidget {
+  const PageGame({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
 
         return Container(
           alignment: AlignmentDirectional.topCenter,
@@ -30,7 +30,7 @@ class GameLayout extends StatelessWidget {
               const SizedBox(height: 8),
               const GameBottomWidget(),
               const Expanded(child: SizedBox.shrink()),
-              currentGame.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
+              currentActivity.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
             ],
           ),
         );
diff --git a/lib/common/ui/pages/parameters.dart b/lib/common/ui/pages/parameters.dart
new file mode 100644
index 0000000000000000000000000000000000000000..d93a8cef65ac452d8a50daa557deeb220b9c9799
--- /dev/null
+++ b/lib/common/ui/pages/parameters.dart
@@ -0,0 +1,148 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/common/ui/parameters/parameter_widget.dart';
+
+import 'package:sudoku/config/default_activity_settings.dart';
+import 'package:sudoku/config/default_global_settings.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/cubit/settings/settings_activity_cubit.dart';
+import 'package:sudoku/cubit/settings/settings_global_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
+import 'package:sudoku/ui/widgets/actions/button_delete_saved_game.dart';
+import 'package:sudoku/ui/widgets/actions/button_game_start_new.dart';
+import 'package:sudoku/ui/widgets/actions/button_resume_saved_game.dart';
+
+class PageParameters extends StatelessWidget {
+  const PageParameters({super.key});
+
+  final double separatorHeight = 8.0;
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
+
+        final List<Widget> lines = [];
+
+        // Game settings
+        for (String code in DefaultActivitySettings.availableParameters) {
+          lines.add(Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: buildParametersLine(
+              code: code,
+              isGlobal: false,
+            ),
+          ));
+
+          lines.add(SizedBox(height: separatorHeight));
+        }
+
+        lines.add(Expanded(
+          child: SizedBox(height: separatorHeight),
+        ));
+
+        if (currentActivity.canBeResumed == false) {
+          // Start new game
+          lines.add(
+            const AspectRatio(
+              aspectRatio: 3,
+              child: StartNewGameButton(),
+            ),
+          );
+        } else {
+          // Resume game
+          lines.add(const AspectRatio(
+            aspectRatio: 3,
+            child: ResumeSavedGameButton(),
+          ));
+          // Delete saved game
+          lines.add(SizedBox.square(
+            dimension: MediaQuery.of(context).size.width / 5,
+            child: const DeleteSavedGameButton(),
+          ));
+        }
+
+        lines.add(SizedBox(height: separatorHeight));
+
+        // Global settings
+        for (String code in DefaultGlobalSettings.availableParameters) {
+          lines.add(Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: buildParametersLine(
+              code: code,
+              isGlobal: true,
+            ),
+          ));
+
+          lines.add(SizedBox(height: separatorHeight));
+        }
+
+        return Column(
+          children: lines,
+        );
+      },
+    );
+  }
+
+  List<Widget> buildParametersLine({
+    required String code,
+    required bool isGlobal,
+  }) {
+    final List<Widget> parameterButtons = [];
+
+    final List<String> availableValues = isGlobal
+        ? DefaultGlobalSettings.getAvailableValues(code)
+        : DefaultActivitySettings.getAvailableValues(code);
+
+    if (availableValues.length <= 1) {
+      return [];
+    }
+
+    for (String value in availableValues) {
+      final Widget parameterButton = BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
+        builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
+          return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
+            builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
+              final ActivitySettingsCubit activitySettingsCubit =
+                  BlocProvider.of<ActivitySettingsCubit>(context);
+              final GlobalSettingsCubit globalSettingsCubit =
+                  BlocProvider.of<GlobalSettingsCubit>(context);
+
+              final String currentValue = isGlobal
+                  ? globalSettingsCubit.getParameterValue(code)
+                  : activitySettingsCubit.getParameterValue(code);
+
+              final bool isSelected = (value == currentValue);
+
+              final double displayWidth = MediaQuery.of(context).size.width;
+              final double itemWidth = displayWidth / availableValues.length - 4;
+
+              return SizedBox.square(
+                dimension: itemWidth,
+                child: ParameterWidget(
+                  code: code,
+                  value: value,
+                  isSelected: isSelected,
+                  size: itemWidth,
+                  activitySettings: activitySettingsState.settings,
+                  globalSettings: globalSettingsState.settings,
+                  onPressed: () {
+                    isGlobal
+                        ? globalSettingsCubit.setParameterValue(code, value)
+                        : activitySettingsCubit.setParameterValue(code, value);
+                  },
+                ),
+              );
+            },
+          );
+        },
+      );
+
+      parameterButtons.add(parameterButton);
+    }
+
+    return parameterButtons;
+  }
+}
diff --git a/lib/ui/parameters/parameter_painter.dart b/lib/common/ui/parameters/parameter_painter.dart
similarity index 85%
rename from lib/ui/parameters/parameter_painter.dart
rename to lib/common/ui/parameters/parameter_painter.dart
index e83e6fb1aa76a727141fb19bc2fb1e971f036579..182b1f3aacca6e2b50245ab97e3c52d1bc6cb721 100644
--- a/lib/ui/parameters/parameter_painter.dart
+++ b/lib/common/ui/parameters/parameter_painter.dart
@@ -3,21 +3,21 @@ import 'dart:math';
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/config/default_game_settings.dart';
-import 'package:sudoku/models/settings/settings_game.dart';
+import 'package:sudoku/config/default_activity_settings.dart';
+import 'package:sudoku/models/settings/settings_activity.dart';
 import 'package:sudoku/models/settings/settings_global.dart';
 
 class ParameterPainter extends CustomPainter {
   const ParameterPainter({
     required this.code,
     required this.value,
-    required this.gameSettings,
+    required this.activitySettings,
     required this.globalSettings,
   });
 
   final String code;
   final String value;
-  final GameSettings gameSettings;
+  final ActivitySettings activitySettings;
   final GlobalSettings globalSettings;
 
   @override
@@ -27,10 +27,10 @@ class ParameterPainter extends CustomPainter {
 
     // content
     switch (code) {
-      case DefaultGameSettings.parameterCodeLevel:
+      case DefaultActivitySettings.parameterCodeLevel:
         paintLevelParameterItem(canvas, canvasSize);
         break;
-      case DefaultGameSettings.parameterCodeSize:
+      case DefaultActivitySettings.parameterCodeSize:
         paintSizeParameterItem(canvas, canvasSize);
         break;
       default:
@@ -83,19 +83,19 @@ class ParameterPainter extends CustomPainter {
     final List<dynamic> stars = [];
 
     switch (value) {
-      case DefaultGameSettings.levelValueEasy:
+      case DefaultActivitySettings.levelValueEasy:
         stars.add([0.5, 0.5]);
         break;
-      case DefaultGameSettings.levelValueMedium:
+      case DefaultActivitySettings.levelValueMedium:
         stars.add([0.3, 0.5]);
         stars.add([0.7, 0.5]);
         break;
-      case DefaultGameSettings.levelValueHard:
+      case DefaultActivitySettings.levelValueHard:
         stars.add([0.3, 0.3]);
         stars.add([0.7, 0.3]);
         stars.add([0.5, 0.7]);
         break;
-      case DefaultGameSettings.levelValueNightmare:
+      case DefaultActivitySettings.levelValueNightmare:
         stars.add([0.3, 0.3]);
         stars.add([0.7, 0.3]);
         stars.add([0.3, 0.7]);
@@ -144,19 +144,19 @@ class ParameterPainter extends CustomPainter {
     int gridHeight = 1;
 
     switch (value) {
-      case DefaultGameSettings.sizeValueTiny:
+      case DefaultActivitySettings.sizeValueTiny:
         gridWidth = 2;
         gridHeight = 2;
         break;
-      case DefaultGameSettings.sizeValueSmall:
+      case DefaultActivitySettings.sizeValueSmall:
         gridWidth = 3;
         gridHeight = 2;
         break;
-      case DefaultGameSettings.sizeValueStandard:
+      case DefaultActivitySettings.sizeValueStandard:
         gridWidth = 3;
         gridHeight = 3;
         break;
-      case DefaultGameSettings.sizeValueLarge:
+      case DefaultActivitySettings.sizeValueLarge:
         gridWidth = 4;
         gridHeight = 4;
         break;
diff --git a/lib/ui/parameters/parameter_widget.dart b/lib/common/ui/parameters/parameter_widget.dart
similarity index 80%
rename from lib/ui/parameters/parameter_widget.dart
rename to lib/common/ui/parameters/parameter_widget.dart
index 09eb967e7afd90a0fb2d4964368f2a193c4c573c..1eec514bb6305401538a215f82fd266befef49ce 100644
--- a/lib/ui/parameters/parameter_widget.dart
+++ b/lib/common/ui/parameters/parameter_widget.dart
@@ -1,11 +1,12 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/config/default_game_settings.dart';
+import 'package:sudoku/common/ui/parameters/parameter_painter.dart';
+
+import 'package:sudoku/config/default_activity_settings.dart';
 import 'package:sudoku/config/default_global_settings.dart';
-import 'package:sudoku/models/settings/settings_game.dart';
+import 'package:sudoku/models/settings/settings_activity.dart';
 import 'package:sudoku/models/settings/settings_global.dart';
-import 'package:sudoku/ui/parameters/parameter_painter.dart';
 
 class ParameterWidget extends StatelessWidget {
   const ParameterWidget({
@@ -14,7 +15,7 @@ class ParameterWidget extends StatelessWidget {
     required this.value,
     required this.isSelected,
     required this.size,
-    required this.gameSettings,
+    required this.activitySettings,
     required this.globalSettings,
     required this.onPressed,
   });
@@ -23,7 +24,7 @@ class ParameterWidget extends StatelessWidget {
   final String value;
   final bool isSelected;
   final double size;
-  final GameSettings gameSettings;
+  final ActivitySettings activitySettings;
   final GlobalSettings globalSettings;
   final VoidCallback onPressed;
 
@@ -37,10 +38,10 @@ class ParameterWidget extends StatelessWidget {
     Widget content = const SizedBox.shrink();
 
     switch (code) {
-      case DefaultGameSettings.parameterCodeLevel:
+      case DefaultActivitySettings.parameterCodeLevel:
         content = getLevelParameterItem();
         break;
-      case DefaultGameSettings.parameterCodeSize:
+      case DefaultActivitySettings.parameterCodeSize:
         content = getSizeParameterItem();
         break;
       case DefaultGlobalSettings.parameterCodeSkin:
@@ -79,16 +80,16 @@ class ParameterWidget extends StatelessWidget {
     Color backgroundColor = Colors.grey;
 
     switch (value) {
-      case DefaultGameSettings.levelValueEasy:
+      case DefaultActivitySettings.levelValueEasy:
         backgroundColor = Colors.green;
         break;
-      case DefaultGameSettings.levelValueMedium:
+      case DefaultActivitySettings.levelValueMedium:
         backgroundColor = Colors.orange;
         break;
-      case DefaultGameSettings.levelValueHard:
+      case DefaultActivitySettings.levelValueHard:
         backgroundColor = Colors.red;
         break;
-      case DefaultGameSettings.levelValueNightmare:
+      case DefaultActivitySettings.levelValueNightmare:
         backgroundColor = Colors.purple;
         break;
       default:
@@ -104,7 +105,7 @@ class ParameterWidget extends StatelessWidget {
         painter: ParameterPainter(
           code: code,
           value: value,
-          gameSettings: gameSettings,
+          activitySettings: activitySettings,
           globalSettings: globalSettings,
         ),
         isComplex: true,
@@ -116,16 +117,16 @@ class ParameterWidget extends StatelessWidget {
     Color backgroundColor = Colors.grey;
 
     switch (value) {
-      case DefaultGameSettings.sizeValueTiny:
+      case DefaultActivitySettings.sizeValueTiny:
         backgroundColor = Colors.green;
         break;
-      case DefaultGameSettings.sizeValueSmall:
+      case DefaultActivitySettings.sizeValueSmall:
         backgroundColor = Colors.orange;
         break;
-      case DefaultGameSettings.sizeValueStandard:
+      case DefaultActivitySettings.sizeValueStandard:
         backgroundColor = Colors.red;
         break;
-      case DefaultGameSettings.sizeValueLarge:
+      case DefaultActivitySettings.sizeValueLarge:
         backgroundColor = Colors.purple;
         break;
       default:
@@ -141,7 +142,7 @@ class ParameterWidget extends StatelessWidget {
         painter: ParameterPainter(
           code: code,
           value: value,
-          gameSettings: gameSettings,
+          activitySettings: activitySettings,
           globalSettings: globalSettings,
         ),
         isComplex: true,
diff --git a/lib/ui/screens/page_about.dart b/lib/common/ui/screens/about.dart
similarity index 93%
rename from lib/ui/screens/page_about.dart
rename to lib/common/ui/screens/about.dart
index ab73e304b8138295f6669330b928e0d1d0263565..f7a14a9a7e574a7b6f9ed181f38d08ba8c2285fe 100644
--- a/lib/ui/screens/page_about.dart
+++ b/lib/common/ui/screens/about.dart
@@ -1,8 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-class PageAbout extends StatelessWidget {
-  const PageAbout({super.key});
+class ScreenAbout extends StatelessWidget {
+  const ScreenAbout({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/common/ui/screens/activity.dart b/lib/common/ui/screens/activity.dart
new file mode 100644
index 0000000000000000000000000000000000000000..9e71d61ee068797968af86f93868f8241573919b
--- /dev/null
+++ b/lib/common/ui/screens/activity.dart
@@ -0,0 +1,18 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/common/config/activity_page.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_pages.dart';
+
+class ScreenActivity extends StatelessWidget {
+  const ScreenActivity({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<NavCubitPage, int>(
+      builder: (BuildContext context, int pageIndex) {
+        return ActivityPage.getWidget(pageIndex);
+      },
+    );
+  }
+}
diff --git a/lib/ui/screens/page_settings.dart b/lib/common/ui/screens/settings.dart
similarity index 87%
rename from lib/ui/screens/page_settings.dart
rename to lib/common/ui/screens/settings.dart
index 50964ef462b6e3e411347cab4e966afb0f505008..7981b1c6becc4f5b925c3058b05423750d80f62e 100644
--- a/lib/ui/screens/page_settings.dart
+++ b/lib/common/ui/screens/settings.dart
@@ -1,8 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-class PageSettings extends StatelessWidget {
-  const PageSettings({super.key});
+class ScreenSettings extends StatelessWidget {
+  const ScreenSettings({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/config/application_config.dart b/lib/config/application_config.dart
new file mode 100644
index 0000000000000000000000000000000000000000..582766a9b9011a86fc1e6b43619307875b6c6a6a
--- /dev/null
+++ b/lib/config/application_config.dart
@@ -0,0 +1,3 @@
+class ApplicationConfig {
+  static const String appTitle = 'Sudoku';
+}
diff --git a/lib/config/default_game_settings.dart b/lib/config/default_activity_settings.dart
similarity index 91%
rename from lib/config/default_game_settings.dart
rename to lib/config/default_activity_settings.dart
index 00d8e20dd7e6853ab97ee9c5ffc3e994479d4623..9f6ce9ce54715f87bd80c62f930b5fe7ca004051 100644
--- a/lib/config/default_game_settings.dart
+++ b/lib/config/default_activity_settings.dart
@@ -1,6 +1,6 @@
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-class DefaultGameSettings {
+class DefaultActivitySettings {
   // available game parameters codes
   static const String parameterCodeLevel = 'level';
   static const String parameterCodeSize = 'size';
@@ -41,9 +41,9 @@ class DefaultGameSettings {
   static List<String> getAvailableValues(String parameterCode) {
     switch (parameterCode) {
       case parameterCodeLevel:
-        return DefaultGameSettings.allowedLevelValues;
+        return DefaultActivitySettings.allowedLevelValues;
       case parameterCodeSize:
-        return DefaultGameSettings.allowedSizeValues;
+        return DefaultActivitySettings.allowedSizeValues;
     }
 
     printlog('Did not find any available value for game parameter "$parameterCode".');
diff --git a/lib/config/menu.dart b/lib/config/menu.dart
deleted file mode 100644
index d3c7f1e7c10b0b14424703e8f0b943119e776dd9..0000000000000000000000000000000000000000
--- a/lib/config/menu.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:sudoku/ui/screens/page_about.dart';
-import 'package:sudoku/ui/screens/page_game.dart';
-import 'package:sudoku/ui/screens/page_settings.dart';
-
-class MenuItem {
-  final Icon icon;
-  final Widget page;
-
-  const MenuItem({
-    required this.icon,
-    required this.page,
-  });
-}
-
-class Menu {
-  static const indexGame = 0;
-  static const menuItemGame = MenuItem(
-    icon: Icon(UniconsLine.home),
-    page: PageGame(),
-  );
-
-  static const indexSettings = 1;
-  static const menuItemSettings = MenuItem(
-    icon: Icon(UniconsLine.setting),
-    page: PageSettings(),
-  );
-
-  static const indexAbout = 2;
-  static const menuItemAbout = MenuItem(
-    icon: Icon(UniconsLine.info_circle),
-    page: PageAbout(),
-  );
-
-  static Map<int, MenuItem> items = {
-    indexGame: menuItemGame,
-    indexSettings: menuItemSettings,
-    indexAbout: menuItemAbout,
-  };
-
-  static bool isIndexAllowed(int pageIndex) {
-    return items.keys.contains(pageIndex);
-  }
-
-  static Widget getPageWidget(int pageIndex) {
-    return items[pageIndex]?.page ?? menuItemGame.page;
-  }
-
-  static int itemsCount = Menu.items.length;
-}
diff --git a/lib/cubit/activity/activity_cubit.dart b/lib/cubit/activity/activity_cubit.dart
new file mode 100644
index 0000000000000000000000000000000000000000..18d8cde9a3a06e811f1bbe0f24ba088364192e8f
--- /dev/null
+++ b/lib/cubit/activity/activity_cubit.dart
@@ -0,0 +1,188 @@
+import 'dart:async';
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/config/default_global_settings.dart';
+import 'package:sudoku/models/activity/cell.dart';
+import 'package:sudoku/models/activity/cell_location.dart';
+import 'package:sudoku/models/activity/activity.dart';
+import 'package:sudoku/models/settings/settings_activity.dart';
+import 'package:sudoku/models/settings/settings_global.dart';
+import 'package:sudoku/utils/board_animate.dart';
+
+part 'activity_state.dart';
+
+class ActivityCubit extends HydratedCubit<ActivityState> {
+  ActivityCubit()
+      : super(ActivityState(
+          currentActivity: Activity.createEmpty(),
+        ));
+
+  void updateState(Activity activity) {
+    emit(ActivityState(
+      currentActivity: activity,
+    ));
+  }
+
+  void refresh() {
+    final Activity activity = Activity(
+      // Settings
+      activitySettings: state.currentActivity.activitySettings,
+      globalSettings: state.currentActivity.globalSettings,
+      // State
+      isRunning: state.currentActivity.isRunning,
+      isStarted: state.currentActivity.isStarted,
+      isFinished: state.currentActivity.isFinished,
+      animationInProgress: state.currentActivity.animationInProgress,
+      boardAnimated: state.currentActivity.boardAnimated,
+      // Base data
+      board: state.currentActivity.board,
+      solvedBoard: state.currentActivity.solvedBoard,
+      blockSizeHorizontal: state.currentActivity.blockSizeHorizontal,
+      blockSizeVertical: state.currentActivity.blockSizeVertical,
+      boardSize: state.currentActivity.boardSize,
+      // Game data
+      shuffledCellValues: state.currentActivity.shuffledCellValues,
+      boardConflicts: state.currentActivity.boardConflicts,
+      selectedCell: state.currentActivity.selectedCell,
+      showConflicts: state.currentActivity.showConflicts,
+      givenTipsCount: state.currentActivity.givenTipsCount,
+      buttonTipsCountdown: state.currentActivity.buttonTipsCountdown,
+    );
+    // game.dump();
+
+    updateState(activity);
+  }
+
+  void startNewActivity({
+    required ActivitySettings activitySettings,
+    required GlobalSettings globalSettings,
+  }) {
+    final Activity newActivity = Activity.createNew(
+      // Settings
+      activitySettings: activitySettings,
+      globalSettings: globalSettings,
+    );
+
+    newActivity.dump();
+
+    updateState(newActivity);
+    refresh();
+
+    BoardAnimate.startAnimation(this, 'start');
+  }
+
+  void selectCell(CellLocation location) {
+    state.currentActivity.selectedCell = state.currentActivity.board.get(location);
+    refresh();
+  }
+
+  void unselectCell() {
+    state.currentActivity.selectedCell = null;
+    refresh();
+  }
+
+  void updateCellValue(CellLocation location, int value) {
+    if (state.currentActivity.board.get(location).isFixed == false) {
+      state.currentActivity.board.set(
+        location,
+        Cell(
+          location: location,
+          value: value,
+          isFixed: false,
+        ),
+      );
+      state.currentActivity.isStarted = true;
+      refresh();
+    }
+
+    if (state.currentActivity.checkBoardIsSolved()) {
+      BoardAnimate.startAnimation(this, 'win');
+      state.currentActivity.isFinished = true;
+      refresh();
+    }
+  }
+
+  void toggleShowConflicts() {
+    state.currentActivity.showConflicts = !state.currentActivity.showConflicts;
+    refresh();
+  }
+
+  void increaseGivenTipsCount() {
+    state.currentActivity.givenTipsCount++;
+    state.currentActivity.buttonTipsCountdown =
+        DefaultGlobalSettings.defaultTipCountDownValueInSeconds;
+    refresh();
+
+    const Duration interval = Duration(milliseconds: 500);
+    Timer.periodic(
+      interval,
+      (Timer timer) {
+        if (state.currentActivity.buttonTipsCountdown == 0) {
+          timer.cancel();
+        } else {
+          state.currentActivity.buttonTipsCountdown =
+              max(state.currentActivity.buttonTipsCountdown - 1, 0);
+        }
+        refresh();
+      },
+    );
+  }
+
+  void quitActivity() {
+    state.currentActivity.isRunning = false;
+    refresh();
+  }
+
+  void resumeSavedActivity() {
+    state.currentActivity.isRunning = true;
+    refresh();
+  }
+
+  void deleteSavedActivity() {
+    state.currentActivity.isRunning = false;
+    state.currentActivity.isFinished = true;
+    refresh();
+  }
+
+  void updateAnimationInProgress(bool animationInProgress) {
+    state.currentActivity.animationInProgress = animationInProgress;
+    refresh();
+  }
+
+  void setAnimatedBackground(List animatedCellsPattern) {
+    for (int row = 0; row < state.currentActivity.boardSize; row++) {
+      for (int col = 0; col < state.currentActivity.boardSize; col++) {
+        state.currentActivity.boardAnimated[row][col] = animatedCellsPattern[row][col];
+      }
+    }
+    refresh();
+  }
+
+  void resetAnimatedBackground() {
+    for (int row = 0; row < state.currentActivity.boardSize; row++) {
+      for (int col = 0; col < state.currentActivity.boardSize; col++) {
+        state.currentActivity.boardAnimated[row][col] = false;
+      }
+    }
+    refresh();
+  }
+
+  @override
+  ActivityState? fromJson(Map<String, dynamic> json) {
+    final Activity currentActivity = json['currentActivity'] as Activity;
+
+    return ActivityState(
+      currentActivity: currentActivity,
+    );
+  }
+
+  @override
+  Map<String, dynamic>? toJson(ActivityState state) {
+    return <String, dynamic>{
+      'currentActivity': state.currentActivity.toJson(),
+    };
+  }
+}
diff --git a/lib/cubit/activity/activity_state.dart b/lib/cubit/activity/activity_state.dart
new file mode 100644
index 0000000000000000000000000000000000000000..887b45e4255fd7de1cc7744569d82a38a66602f2
--- /dev/null
+++ b/lib/cubit/activity/activity_state.dart
@@ -0,0 +1,15 @@
+part of 'activity_cubit.dart';
+
+@immutable
+class ActivityState extends Equatable {
+  const ActivityState({
+    required this.currentActivity,
+  });
+
+  final Activity currentActivity;
+
+  @override
+  List<dynamic> get props => <dynamic>[
+        currentActivity,
+      ];
+}
diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart
deleted file mode 100644
index 0faf02ae65ea6778b03818cc739843f2a21bf6b7..0000000000000000000000000000000000000000
--- a/lib/cubit/game_cubit.dart
+++ /dev/null
@@ -1,188 +0,0 @@
-import 'dart:async';
-import 'dart:math';
-
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:sudoku/config/default_global_settings.dart';
-import 'package:sudoku/models/game/cell.dart';
-import 'package:sudoku/models/game/cell_location.dart';
-import 'package:sudoku/models/game/game.dart';
-import 'package:sudoku/models/settings/settings_game.dart';
-import 'package:sudoku/models/settings/settings_global.dart';
-import 'package:sudoku/utils/board_animate.dart';
-
-part 'game_state.dart';
-
-class GameCubit extends HydratedCubit<GameState> {
-  GameCubit()
-      : super(GameState(
-          currentGame: Game.createEmpty(),
-        ));
-
-  void updateState(Game game) {
-    emit(GameState(
-      currentGame: game,
-    ));
-  }
-
-  void refresh() {
-    final Game game = Game(
-      // Settings
-      gameSettings: state.currentGame.gameSettings,
-      globalSettings: state.currentGame.globalSettings,
-      // State
-      isRunning: state.currentGame.isRunning,
-      isStarted: state.currentGame.isStarted,
-      isFinished: state.currentGame.isFinished,
-      animationInProgress: state.currentGame.animationInProgress,
-      boardAnimated: state.currentGame.boardAnimated,
-      // Base data
-      board: state.currentGame.board,
-      solvedBoard: state.currentGame.solvedBoard,
-      blockSizeHorizontal: state.currentGame.blockSizeHorizontal,
-      blockSizeVertical: state.currentGame.blockSizeVertical,
-      boardSize: state.currentGame.boardSize,
-      // Game data
-      shuffledCellValues: state.currentGame.shuffledCellValues,
-      boardConflicts: state.currentGame.boardConflicts,
-      selectedCell: state.currentGame.selectedCell,
-      showConflicts: state.currentGame.showConflicts,
-      givenTipsCount: state.currentGame.givenTipsCount,
-      buttonTipsCountdown: state.currentGame.buttonTipsCountdown,
-    );
-    // game.dump();
-
-    updateState(game);
-  }
-
-  void startNewGame({
-    required GameSettings gameSettings,
-    required GlobalSettings globalSettings,
-  }) {
-    final Game newGame = Game.createNew(
-      // Settings
-      gameSettings: gameSettings,
-      globalSettings: globalSettings,
-    );
-
-    newGame.dump();
-
-    updateState(newGame);
-    refresh();
-
-    BoardAnimate.startAnimation(this, 'start');
-  }
-
-  void selectCell(CellLocation location) {
-    state.currentGame.selectedCell = state.currentGame.board.get(location);
-    refresh();
-  }
-
-  void unselectCell() {
-    state.currentGame.selectedCell = null;
-    refresh();
-  }
-
-  void updateCellValue(CellLocation location, int value) {
-    if (state.currentGame.board.get(location).isFixed == false) {
-      state.currentGame.board.set(
-        location,
-        Cell(
-          location: location,
-          value: value,
-          isFixed: false,
-        ),
-      );
-      state.currentGame.isStarted = true;
-      refresh();
-    }
-
-    if (state.currentGame.checkBoardIsSolved()) {
-      BoardAnimate.startAnimation(this, 'win');
-      state.currentGame.isFinished = true;
-      refresh();
-    }
-  }
-
-  void toggleShowConflicts() {
-    state.currentGame.showConflicts = !state.currentGame.showConflicts;
-    refresh();
-  }
-
-  void increaseGivenTipsCount() {
-    state.currentGame.givenTipsCount++;
-    state.currentGame.buttonTipsCountdown =
-        DefaultGlobalSettings.defaultTipCountDownValueInSeconds;
-    refresh();
-
-    const Duration interval = Duration(milliseconds: 500);
-    Timer.periodic(
-      interval,
-      (Timer timer) {
-        if (state.currentGame.buttonTipsCountdown == 0) {
-          timer.cancel();
-        } else {
-          state.currentGame.buttonTipsCountdown =
-              max(state.currentGame.buttonTipsCountdown - 1, 0);
-        }
-        refresh();
-      },
-    );
-  }
-
-  void quitGame() {
-    state.currentGame.isRunning = false;
-    refresh();
-  }
-
-  void resumeSavedGame() {
-    state.currentGame.isRunning = true;
-    refresh();
-  }
-
-  void deleteSavedGame() {
-    state.currentGame.isRunning = false;
-    state.currentGame.isFinished = true;
-    refresh();
-  }
-
-  void updateAnimationInProgress(bool animationInProgress) {
-    state.currentGame.animationInProgress = animationInProgress;
-    refresh();
-  }
-
-  void setAnimatedBackground(List animatedCellsPattern) {
-    for (int row = 0; row < state.currentGame.boardSize; row++) {
-      for (int col = 0; col < state.currentGame.boardSize; col++) {
-        state.currentGame.boardAnimated[row][col] = animatedCellsPattern[row][col];
-      }
-    }
-    refresh();
-  }
-
-  void resetAnimatedBackground() {
-    for (int row = 0; row < state.currentGame.boardSize; row++) {
-      for (int col = 0; col < state.currentGame.boardSize; col++) {
-        state.currentGame.boardAnimated[row][col] = false;
-      }
-    }
-    refresh();
-  }
-
-  @override
-  GameState? fromJson(Map<String, dynamic> json) {
-    final Game currentGame = json['currentGame'] as Game;
-
-    return GameState(
-      currentGame: currentGame,
-    );
-  }
-
-  @override
-  Map<String, dynamic>? toJson(GameState state) {
-    return <String, dynamic>{
-      'currentGame': state.currentGame.toJson(),
-    };
-  }
-}
diff --git a/lib/cubit/game_state.dart b/lib/cubit/game_state.dart
deleted file mode 100644
index 00e211668c3269255926939324355792abd61c41..0000000000000000000000000000000000000000
--- a/lib/cubit/game_state.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-part of 'game_cubit.dart';
-
-@immutable
-class GameState extends Equatable {
-  const GameState({
-    required this.currentGame,
-  });
-
-  final Game currentGame;
-
-  @override
-  List<dynamic> get props => <dynamic>[
-        currentGame,
-      ];
-}
diff --git a/lib/cubit/nav_cubit.dart b/lib/cubit/nav_cubit.dart
deleted file mode 100644
index b224fae946671af23e7cbc8eb2f4b05fc8bf1448..0000000000000000000000000000000000000000
--- a/lib/cubit/nav_cubit.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:sudoku/config/menu.dart';
-
-class NavCubit extends HydratedCubit<int> {
-  NavCubit() : super(0);
-
-  void updateIndex(int index) {
-    if (Menu.isIndexAllowed(index)) {
-      emit(index);
-    } else {
-      goToGamePage();
-    }
-  }
-
-  void goToGamePage() {
-    emit(Menu.indexGame);
-  }
-
-  void goToSettingsPage() {
-    emit(Menu.indexSettings);
-  }
-
-  void goToAboutPage() {
-    emit(Menu.indexAbout);
-  }
-
-  @override
-  int fromJson(Map<String, dynamic> json) {
-    return Menu.indexGame;
-  }
-
-  @override
-  Map<String, dynamic>? toJson(int state) {
-    return <String, int>{'pageIndex': state};
-  }
-}
diff --git a/lib/cubit/settings/settings_activity_cubit.dart b/lib/cubit/settings/settings_activity_cubit.dart
new file mode 100644
index 0000000000000000000000000000000000000000..1d82f83804346185a268c246097921aa31d05398
--- /dev/null
+++ b/lib/cubit/settings/settings_activity_cubit.dart
@@ -0,0 +1,72 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/config/default_activity_settings.dart';
+import 'package:sudoku/models/settings/settings_activity.dart';
+
+part 'settings_activity_state.dart';
+
+class ActivitySettingsCubit extends HydratedCubit<ActivitySettingsState> {
+  ActivitySettingsCubit()
+      : super(ActivitySettingsState(settings: ActivitySettings.createDefault()));
+
+  void setValues({
+    String? level,
+    String? size,
+  }) {
+    emit(
+      ActivitySettingsState(
+        settings: ActivitySettings(
+          level: level ?? state.settings.level,
+          size: size ?? state.settings.size,
+        ),
+      ),
+    );
+  }
+
+  String getParameterValue(String code) {
+    switch (code) {
+      case DefaultActivitySettings.parameterCodeLevel:
+        return ActivitySettings.getLevelValueFromUnsafe(state.settings.level);
+      case DefaultActivitySettings.parameterCodeSize:
+        return ActivitySettings.getSizeValueFromUnsafe(state.settings.size);
+    }
+
+    return '';
+  }
+
+  void setParameterValue(String code, String value) {
+    final String level = (code == DefaultActivitySettings.parameterCodeLevel)
+        ? value
+        : getParameterValue(DefaultActivitySettings.parameterCodeLevel);
+    final String size = (code == DefaultActivitySettings.parameterCodeSize)
+        ? value
+        : getParameterValue(DefaultActivitySettings.parameterCodeSize);
+
+    setValues(
+      level: level,
+      size: size,
+    );
+  }
+
+  @override
+  ActivitySettingsState? fromJson(Map<String, dynamic> json) {
+    final String level = json[DefaultActivitySettings.parameterCodeLevel] as String;
+    final String size = json[DefaultActivitySettings.parameterCodeSize] as String;
+
+    return ActivitySettingsState(
+      settings: ActivitySettings(
+        level: level,
+        size: size,
+      ),
+    );
+  }
+
+  @override
+  Map<String, dynamic>? toJson(ActivitySettingsState state) {
+    return <String, dynamic>{
+      DefaultActivitySettings.parameterCodeLevel: state.settings.level,
+      DefaultActivitySettings.parameterCodeSize: state.settings.size,
+    };
+  }
+}
diff --git a/lib/cubit/settings/settings_activity_state.dart b/lib/cubit/settings/settings_activity_state.dart
new file mode 100644
index 0000000000000000000000000000000000000000..2b2de42011634e81ae9e6f8bcaa1577f239c778b
--- /dev/null
+++ b/lib/cubit/settings/settings_activity_state.dart
@@ -0,0 +1,15 @@
+part of 'settings_activity_cubit.dart';
+
+@immutable
+class ActivitySettingsState extends Equatable {
+  const ActivitySettingsState({
+    required this.settings,
+  });
+
+  final ActivitySettings settings;
+
+  @override
+  List<dynamic> get props => <dynamic>[
+        settings,
+      ];
+}
diff --git a/lib/cubit/settings_global_cubit.dart b/lib/cubit/settings/settings_global_cubit.dart
similarity index 100%
rename from lib/cubit/settings_global_cubit.dart
rename to lib/cubit/settings/settings_global_cubit.dart
diff --git a/lib/cubit/settings_global_state.dart b/lib/cubit/settings/settings_global_state.dart
similarity index 100%
rename from lib/cubit/settings_global_state.dart
rename to lib/cubit/settings/settings_global_state.dart
diff --git a/lib/cubit/settings_game_cubit.dart b/lib/cubit/settings_game_cubit.dart
deleted file mode 100644
index 65111b0ec024e045c6bf304db11b39d94effbe16..0000000000000000000000000000000000000000
--- a/lib/cubit/settings_game_cubit.dart
+++ /dev/null
@@ -1,71 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:sudoku/config/default_game_settings.dart';
-import 'package:sudoku/models/settings/settings_game.dart';
-
-part 'settings_game_state.dart';
-
-class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
-  GameSettingsCubit() : super(GameSettingsState(settings: GameSettings.createDefault()));
-
-  void setValues({
-    String? level,
-    String? size,
-  }) {
-    emit(
-      GameSettingsState(
-        settings: GameSettings(
-          level: level ?? state.settings.level,
-          size: size ?? state.settings.size,
-        ),
-      ),
-    );
-  }
-
-  String getParameterValue(String code) {
-    switch (code) {
-      case DefaultGameSettings.parameterCodeLevel:
-        return GameSettings.getLevelValueFromUnsafe(state.settings.level);
-      case DefaultGameSettings.parameterCodeSize:
-        return GameSettings.getSizeValueFromUnsafe(state.settings.size);
-    }
-
-    return '';
-  }
-
-  void setParameterValue(String code, String value) {
-    final String level = (code == DefaultGameSettings.parameterCodeLevel)
-        ? value
-        : getParameterValue(DefaultGameSettings.parameterCodeLevel);
-    final String size = (code == DefaultGameSettings.parameterCodeSize)
-        ? value
-        : getParameterValue(DefaultGameSettings.parameterCodeSize);
-
-    setValues(
-      level: level,
-      size: size,
-    );
-  }
-
-  @override
-  GameSettingsState? fromJson(Map<String, dynamic> json) {
-    final String level = json[DefaultGameSettings.parameterCodeLevel] as String;
-    final String size = json[DefaultGameSettings.parameterCodeSize] as String;
-
-    return GameSettingsState(
-      settings: GameSettings(
-        level: level,
-        size: size,
-      ),
-    );
-  }
-
-  @override
-  Map<String, dynamic>? toJson(GameSettingsState state) {
-    return <String, dynamic>{
-      DefaultGameSettings.parameterCodeLevel: state.settings.level,
-      DefaultGameSettings.parameterCodeSize: state.settings.size,
-    };
-  }
-}
diff --git a/lib/cubit/settings_game_state.dart b/lib/cubit/settings_game_state.dart
deleted file mode 100644
index 5acd85b44ba541e1c5e9c26af1c4be26a385b9ed..0000000000000000000000000000000000000000
--- a/lib/cubit/settings_game_state.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-part of 'settings_game_cubit.dart';
-
-@immutable
-class GameSettingsState extends Equatable {
-  const GameSettingsState({
-    required this.settings,
-  });
-
-  final GameSettings settings;
-
-  @override
-  List<dynamic> get props => <dynamic>[
-        settings,
-      ];
-}
diff --git a/lib/main.dart b/lib/main.dart
index 36564213dbb504959161bd18b10750c0faea6698..ead3d7fa619a3def2272851ddfc0f826c05e2631 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -4,11 +4,14 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
+import 'package:sudoku/common/cubit/nav/nav_cubit_pages.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_screens.dart';
+
+import 'package:sudoku/config/application_config.dart';
 import 'package:sudoku/config/default_global_settings.dart';
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/cubit/nav_cubit.dart';
-import 'package:sudoku/cubit/settings_game_cubit.dart';
-import 'package:sudoku/cubit/settings_global_cubit.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/cubit/settings/settings_activity_cubit.dart';
+import 'package:sudoku/cubit/settings/settings_global_cubit.dart';
 import 'package:sudoku/ui/skeleton.dart';
 
 void main() async {
@@ -46,17 +49,30 @@ class MyApp extends StatelessWidget {
 
     return MultiBlocProvider(
       providers: [
-        BlocProvider<NavCubit>(create: (context) => NavCubit()),
+        // default providers
+        BlocProvider<NavCubitPage>(
+          create: (context) => NavCubitPage(),
+        ),
+        BlocProvider<NavCubitScreen>(
+          create: (context) => NavCubitScreen(),
+        ),
         BlocProvider<ApplicationThemeModeCubit>(
-            create: (context) => ApplicationThemeModeCubit()),
-        BlocProvider<GameCubit>(create: (context) => GameCubit()),
-        BlocProvider<GlobalSettingsCubit>(create: (context) => GlobalSettingsCubit()),
-        BlocProvider<GameSettingsCubit>(create: (context) => GameSettingsCubit()),
+          create: (context) => ApplicationThemeModeCubit(),
+        ),
+        BlocProvider<ActivityCubit>(
+          create: (context) => ActivityCubit(),
+        ),
+        BlocProvider<GlobalSettingsCubit>(
+          create: (context) => GlobalSettingsCubit(),
+        ),
+        BlocProvider<ActivitySettingsCubit>(
+          create: (context) => ActivitySettingsCubit(),
+        ),
       ],
       child: BlocBuilder<ApplicationThemeModeCubit, ApplicationThemeModeState>(
         builder: (BuildContext context, ApplicationThemeModeState state) {
           return MaterialApp(
-            title: 'Sudoku',
+            title: ApplicationConfig.appTitle,
             home: const SkeletonScreen(),
 
             // Theme stuff
diff --git a/lib/models/game/game.dart b/lib/models/activity/activity.dart
similarity index 86%
rename from lib/models/game/game.dart
rename to lib/models/activity/activity.dart
index e8490ff8310dcaf57d9fe49f9a1e29e8a85a6808..c7f312d6b59f13fa947c735615f2b4edaadf554f 100644
--- a/lib/models/game/game.dart
+++ b/lib/models/activity/activity.dart
@@ -3,19 +3,19 @@ import 'dart:math';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:sudoku/config/default_global_settings.dart';
-import 'package:sudoku/cubit/game_cubit.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
 import 'package:sudoku/data/game_data.dart';
-import 'package:sudoku/models/game/board.dart';
-import 'package:sudoku/models/game/cell.dart';
-import 'package:sudoku/models/game/cell_location.dart';
-import 'package:sudoku/models/game/types.dart';
-import 'package:sudoku/models/settings/settings_game.dart';
+import 'package:sudoku/models/activity/board.dart';
+import 'package:sudoku/models/activity/cell.dart';
+import 'package:sudoku/models/activity/cell_location.dart';
+import 'package:sudoku/models/activity/types.dart';
+import 'package:sudoku/models/settings/settings_activity.dart';
 import 'package:sudoku/models/settings/settings_global.dart';
 
-class Game {
-  Game({
+class Activity {
+  Activity({
     // Settings
-    required this.gameSettings,
+    required this.activitySettings,
     required this.globalSettings,
 
     // State
@@ -42,7 +42,7 @@ class Game {
   });
 
   // Settings
-  final GameSettings gameSettings;
+  final ActivitySettings activitySettings;
   final GlobalSettings globalSettings;
 
   // State
@@ -67,10 +67,10 @@ class Game {
   int givenTipsCount;
   int buttonTipsCountdown;
 
-  factory Game.createEmpty() {
-    return Game(
+  factory Activity.createEmpty() {
+    return Activity(
       // Settings
-      gameSettings: GameSettings.createDefault(),
+      activitySettings: ActivitySettings.createDefault(),
       globalSettings: GlobalSettings.createDefault(),
       // Base data
       board: Board.createEmpty(),
@@ -84,15 +84,16 @@ class Game {
     );
   }
 
-  factory Game.createNew({
-    GameSettings? gameSettings,
+  factory Activity.createNew({
+    ActivitySettings? activitySettings,
     GlobalSettings? globalSettings,
   }) {
-    final GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
+    final ActivitySettings newActivitySettings =
+        activitySettings ?? ActivitySettings.createDefault();
     final GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
 
-    final int blockSizeHorizontal = int.parse(newGameSettings.size.split('x')[0]);
-    final int blockSizeVertical = int.parse(newGameSettings.size.split('x')[1]);
+    final int blockSizeHorizontal = int.parse(newActivitySettings.size.split('x')[0]);
+    final int blockSizeVertical = int.parse(newActivitySettings.size.split('x')[1]);
     final int boardSize = blockSizeHorizontal * blockSizeVertical;
 
     const int maxCellValue = 16;
@@ -114,12 +115,12 @@ class Game {
     }
 
     final List<String> templates =
-        GameData.templates[newGameSettings.size]?[newGameSettings.level] ?? [];
+        GameData.templates[newActivitySettings.size]?[newActivitySettings.level] ?? [];
     final String template = templates.elementAt(Random().nextInt(templates.length)).toString();
 
     if (template.length != pow(blockSizeHorizontal * blockSizeVertical, 2)) {
       printlog('Failed to get grid template...');
-      return Game.createEmpty();
+      return Activity.createEmpty();
     }
 
     final Board board = Board.createFromTemplate(
@@ -138,9 +139,9 @@ class Game {
       notAnimatedBoard.add(line);
     }
 
-    return Game(
+    return Activity(
       // Settings
-      gameSettings: newGameSettings,
+      activitySettings: newActivitySettings,
       globalSettings: newGlobalSettings,
       // State
       isRunning: true,
@@ -271,36 +272,36 @@ class Game {
     return conflicts;
   }
 
-  void showTip(GameCubit gameCubit) {
+  void showTip(ActivityCubit activityCubit) {
     if (selectedCell == null) {
       // no selected cell -> pick one
-      helpSelectCell(gameCubit);
+      helpSelectCell(activityCubit);
     } else {
       // currently selected cell -> set value
-      helpFillCell(gameCubit);
+      helpFillCell(activityCubit);
     }
-    gameCubit.increaseGivenTipsCount();
+    activityCubit.increaseGivenTipsCount();
   }
 
-  void helpSelectCell(GameCubit gameCubit) {
+  void helpSelectCell(ActivityCubit activityCubit) {
     // pick one of wrong value cells, if found
     final List<List<int>> wrongValueCells = getCellsWithWrongValue();
     if (wrongValueCells.isNotEmpty) {
-      pickRandomFromList(gameCubit, wrongValueCells);
+      pickRandomFromList(activityCubit, wrongValueCells);
       return;
     }
 
     // pick one of conflicting cells, if found
     final List<List<int>> conflictingCells = getCellsWithConflicts();
     if (conflictingCells.isNotEmpty) {
-      pickRandomFromList(gameCubit, conflictingCells);
+      pickRandomFromList(activityCubit, conflictingCells);
       return;
     }
 
     //  pick one form cells with unique non-conflicting candidate value
     final List<List<int>> candidateCells = board.getEmptyCellsWithUniqueAvailableValue();
     if (candidateCells.isNotEmpty) {
-      pickRandomFromList(gameCubit, candidateCells);
+      pickRandomFromList(activityCubit, candidateCells);
       return;
     }
   }
@@ -337,15 +338,15 @@ class Game {
     return cellsWithConflict;
   }
 
-  void pickRandomFromList(GameCubit gameCubit, List<List<int>> cellsCoordinates) {
+  void pickRandomFromList(ActivityCubit activityCubit, List<List<int>> cellsCoordinates) {
     if (cellsCoordinates.isNotEmpty) {
       cellsCoordinates.shuffle();
       final List<int> cell = cellsCoordinates[0];
-      gameCubit.selectCell(CellLocation.go(cell[0], cell[1]));
+      activityCubit.selectCell(CellLocation.go(cell[0], cell[1]));
     }
   }
 
-  void helpFillCell(GameCubit gameCubit) {
+  void helpFillCell(ActivityCubit activityCubit) {
     // Will clean cell if no eligible value found
     int eligibleValue = 0;
 
@@ -358,18 +359,18 @@ class Game {
       }
     }
 
-    gameCubit.updateCellValue(
+    activityCubit.updateCellValue(
         selectedCell!.location, allowedValuesCount == 1 ? eligibleValue : 0);
-    gameCubit.unselectCell();
+    activityCubit.unselectCell();
   }
 
   void dump() {
     printlog('');
     printlog('## Current game dump:');
     printlog('');
-    printlog('$Game:');
+    printlog('$Activity:');
     printlog('  Settings');
-    gameSettings.dump();
+    activitySettings.dump();
     globalSettings.dump();
     printlog('  State');
     printlog('    isRunning: $isRunning');
@@ -414,13 +415,13 @@ class Game {
 
   @override
   String toString() {
-    return '$Game(${toJson()})';
+    return '$Activity(${toJson()})';
   }
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
       // Settings
-      'gameSettings': gameSettings.toJson(),
+      'activitySettings': activitySettings.toJson(),
       'globalSettings': globalSettings.toJson(),
       // State
       'isRunning': isRunning,
diff --git a/lib/models/game/board.dart b/lib/models/activity/board.dart
similarity index 98%
rename from lib/models/game/board.dart
rename to lib/models/activity/board.dart
index aa6d6df2e24d5dfbd6770dc7681949931985fe22..9397f5c57cd2f85aab53a8b771343a4013a5c514 100644
--- a/lib/models/game/board.dart
+++ b/lib/models/activity/board.dart
@@ -2,9 +2,9 @@ import 'dart:math';
 
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/models/game/cell.dart';
-import 'package:sudoku/models/game/cell_location.dart';
-import 'package:sudoku/models/game/types.dart';
+import 'package:sudoku/models/activity/cell.dart';
+import 'package:sudoku/models/activity/cell_location.dart';
+import 'package:sudoku/models/activity/types.dart';
 
 class Board {
   Board({
diff --git a/lib/models/game/cell.dart b/lib/models/activity/cell.dart
similarity index 92%
rename from lib/models/game/cell.dart
rename to lib/models/activity/cell.dart
index ffd7e63567c15754eae955fe69404b34573e6228..c7636d69f005840e771a86d6bda82467c64a7fa9 100644
--- a/lib/models/game/cell.dart
+++ b/lib/models/activity/cell.dart
@@ -1,6 +1,6 @@
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/models/game/cell_location.dart';
+import 'package:sudoku/models/activity/cell_location.dart';
 
 class Cell {
   const Cell({
diff --git a/lib/models/game/cell_location.dart b/lib/models/activity/cell_location.dart
similarity index 100%
rename from lib/models/game/cell_location.dart
rename to lib/models/activity/cell_location.dart
diff --git a/lib/models/game/types.dart b/lib/models/activity/types.dart
similarity index 77%
rename from lib/models/game/types.dart
rename to lib/models/activity/types.dart
index 6fbdd107b12abaf5ba11a24f6dfdd8a6847c01cd..9a8b13a4978aac808e4f1c970385c5d1c760830b 100644
--- a/lib/models/game/types.dart
+++ b/lib/models/activity/types.dart
@@ -1,4 +1,4 @@
-import 'package:sudoku/models/game/cell.dart';
+import 'package:sudoku/models/activity/cell.dart';
 
 typedef BoardCells = List<List<Cell>>;
 typedef ConflictsCount = List<List<int>>;
diff --git a/lib/models/settings/settings_activity.dart b/lib/models/settings/settings_activity.dart
new file mode 100644
index 0000000000000000000000000000000000000000..8884739bb283b60efc59c287f235746a02fb8b9e
--- /dev/null
+++ b/lib/models/settings/settings_activity.dart
@@ -0,0 +1,55 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:sudoku/config/default_activity_settings.dart';
+
+class ActivitySettings {
+  final String level;
+  final String size;
+
+  ActivitySettings({
+    required this.level,
+    required this.size,
+  });
+
+  static String getLevelValueFromUnsafe(String level) {
+    if (DefaultActivitySettings.allowedLevelValues.contains(level)) {
+      return level;
+    }
+
+    return DefaultActivitySettings.defaultLevelValue;
+  }
+
+  static String getSizeValueFromUnsafe(String size) {
+    if (DefaultActivitySettings.allowedSizeValues.contains(size)) {
+      return size;
+    }
+
+    return DefaultActivitySettings.defaultSizeValue;
+  }
+
+  factory ActivitySettings.createDefault() {
+    return ActivitySettings(
+      level: DefaultActivitySettings.defaultLevelValue,
+      size: DefaultActivitySettings.defaultSizeValue,
+    );
+  }
+
+  void dump() {
+    printlog('$ActivitySettings:');
+    printlog('  ${DefaultActivitySettings.parameterCodeLevel}: $level');
+    printlog('  ${DefaultActivitySettings.parameterCodeSize}: $size');
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$ActivitySettings(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      DefaultActivitySettings.parameterCodeLevel: level,
+      DefaultActivitySettings.parameterCodeSize: size,
+    };
+  }
+}
diff --git a/lib/models/settings/settings_game.dart b/lib/models/settings/settings_game.dart
deleted file mode 100644
index 5b7c005acb218c4874b7802dd37b42c28d1147b8..0000000000000000000000000000000000000000
--- a/lib/models/settings/settings_game.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:sudoku/config/default_game_settings.dart';
-
-class GameSettings {
-  final String level;
-  final String size;
-
-  GameSettings({
-    required this.level,
-    required this.size,
-  });
-
-  static String getLevelValueFromUnsafe(String level) {
-    if (DefaultGameSettings.allowedLevelValues.contains(level)) {
-      return level;
-    }
-
-    return DefaultGameSettings.defaultLevelValue;
-  }
-
-  static String getSizeValueFromUnsafe(String size) {
-    if (DefaultGameSettings.allowedSizeValues.contains(size)) {
-      return size;
-    }
-
-    return DefaultGameSettings.defaultSizeValue;
-  }
-
-  factory GameSettings.createDefault() {
-    return GameSettings(
-      level: DefaultGameSettings.defaultLevelValue,
-      size: DefaultGameSettings.defaultSizeValue,
-    );
-  }
-
-  void dump() {
-    printlog('$GameSettings:');
-    printlog('  ${DefaultGameSettings.parameterCodeLevel}: $level');
-    printlog('  ${DefaultGameSettings.parameterCodeSize}: $size');
-    printlog('');
-  }
-
-  @override
-  String toString() {
-    return '$GameSettings(${toJson()})';
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{
-      DefaultGameSettings.parameterCodeLevel: level,
-      DefaultGameSettings.parameterCodeSize: size,
-    };
-  }
-}
diff --git a/lib/ui/game/game_bottom.dart b/lib/ui/game/game_bottom.dart
index e6e358d1a1a827ed3cb5d8838bec2772e992d5bf..c807511899c32e557e0ee0bfb43f1192b9f522ec 100644
--- a/lib/ui/game/game_bottom.dart
+++ b/lib/ui/game/game_bottom.dart
@@ -1,8 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
 import 'package:sudoku/ui/widgets/game/bar_select_cell_value.dart';
 
 class GameBottomWidget extends StatelessWidget {
@@ -10,11 +10,13 @@ class GameBottomWidget extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
 
-        return currentGame.isFinished ? const SizedBox.shrink() : const SelectCellValueBar();
+        return currentActivity.isFinished
+            ? const SizedBox.shrink()
+            : const SelectCellValueBar();
       },
     );
   }
diff --git a/lib/ui/game/game_end.dart b/lib/ui/game/game_end.dart
index 62f2bcddf89514b2b7104b74d4911165d5d904ab..2ee0282779a5dcd7805780af0ef2723477e1eeaf 100644
--- a/lib/ui/game/game_end.dart
+++ b/lib/ui/game/game_end.dart
@@ -1,8 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
 import 'package:sudoku/ui/widgets/actions/button_game_quit.dart';
 
 class GameEndWidget extends StatelessWidget {
@@ -10,13 +10,13 @@ class GameEndWidget extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
 
         final Image decorationImage = Image(
           image: AssetImage(
-              currentGame.gameWon ? 'assets/ui/game_win.png' : 'assets/ui/game_fail.png'),
+              currentActivity.gameWon ? 'assets/ui/game_win.png' : 'assets/ui/game_fail.png'),
           fit: BoxFit.fill,
         );
 
@@ -34,7 +34,7 @@ class GameEndWidget extends StatelessWidget {
                   ),
                   Column(
                     children: [
-                      currentGame.animationInProgress == true
+                      currentActivity.animationInProgress == true
                           ? decorationImage
                           : const QuitGameButton()
                     ],
diff --git a/lib/ui/game/game_top.dart b/lib/ui/game/game_top.dart
index 32aace448a3446ec553986c4168515e08bad2587..428b88c3ad843854e876e245dc1e5cee372022c4 100644
--- a/lib/ui/game/game_top.dart
+++ b/lib/ui/game/game_top.dart
@@ -1,8 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
 import 'package:sudoku/ui/widgets/game/button_show_conflicts.dart';
 import 'package:sudoku/ui/widgets/game/button_show_tip.dart';
 
@@ -11,13 +11,13 @@ class GameTopWidget extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
 
         return SizedBox(
           height: 60,
-          child: (currentGame.isRunning && !currentGame.isFinished)
+          child: (currentActivity.isRunning && !currentActivity.isFinished)
               ? const Row(
                   mainAxisAlignment: MainAxisAlignment.end,
                   crossAxisAlignment: CrossAxisAlignment.center,
diff --git a/lib/ui/layouts/parameters_layout.dart b/lib/ui/layouts/parameters_layout.dart
deleted file mode 100644
index 5a16634da4c2bdb932eea9129199f67ed6a123e1..0000000000000000000000000000000000000000
--- a/lib/ui/layouts/parameters_layout.dart
+++ /dev/null
@@ -1,141 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:sudoku/config/default_game_settings.dart';
-import 'package:sudoku/config/default_global_settings.dart';
-import 'package:sudoku/cubit/settings_game_cubit.dart';
-import 'package:sudoku/cubit/settings_global_cubit.dart';
-import 'package:sudoku/ui/parameters/parameter_widget.dart';
-import 'package:sudoku/ui/widgets/actions/button_delete_saved_game.dart';
-import 'package:sudoku/ui/widgets/actions/button_game_start_new.dart';
-import 'package:sudoku/ui/widgets/actions/button_resume_saved_game.dart';
-
-class ParametersLayout extends StatelessWidget {
-  const ParametersLayout({super.key, required this.canResume});
-
-  final bool canResume;
-
-  final double separatorHeight = 8.0;
-
-  @override
-  Widget build(BuildContext context) {
-    final List<Widget> lines = [];
-
-    // Game settings
-    for (String code in DefaultGameSettings.availableParameters) {
-      lines.add(Row(
-        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-        children: buildParametersLine(
-          code: code,
-          isGlobal: false,
-        ),
-      ));
-
-      lines.add(SizedBox(height: separatorHeight));
-    }
-
-    lines.add(Expanded(
-      child: SizedBox(height: separatorHeight),
-    ));
-
-    if (canResume == false) {
-      // Start new game
-      lines.add(
-        const AspectRatio(
-          aspectRatio: 3,
-          child: StartNewGameButton(),
-        ),
-      );
-    } else {
-      // Resume game
-      lines.add(const AspectRatio(
-        aspectRatio: 3,
-        child: ResumeSavedGameButton(),
-      ));
-      // Delete saved game
-      lines.add(SizedBox.square(
-        dimension: MediaQuery.of(context).size.width / 5,
-        child: const DeleteSavedGameButton(),
-      ));
-    }
-
-    lines.add(SizedBox(height: separatorHeight));
-
-    // Global settings
-    for (String code in DefaultGlobalSettings.availableParameters) {
-      lines.add(Row(
-        mainAxisAlignment: MainAxisAlignment.spaceBetween,
-        children: buildParametersLine(
-          code: code,
-          isGlobal: true,
-        ),
-      ));
-
-      lines.add(SizedBox(height: separatorHeight));
-    }
-
-    return Column(
-      children: lines,
-    );
-  }
-
-  List<Widget> buildParametersLine({
-    required String code,
-    required bool isGlobal,
-  }) {
-    final List<Widget> parameterButtons = [];
-
-    final List<String> availableValues = isGlobal
-        ? DefaultGlobalSettings.getAvailableValues(code)
-        : DefaultGameSettings.getAvailableValues(code);
-
-    if (availableValues.length <= 1) {
-      return [];
-    }
-
-    for (String value in availableValues) {
-      final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
-        builder: (BuildContext context, GameSettingsState gameSettingsState) {
-          return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
-            builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
-              final GameSettingsCubit gameSettingsCubit =
-                  BlocProvider.of<GameSettingsCubit>(context);
-              final GlobalSettingsCubit globalSettingsCubit =
-                  BlocProvider.of<GlobalSettingsCubit>(context);
-
-              final String currentValue = isGlobal
-                  ? globalSettingsCubit.getParameterValue(code)
-                  : gameSettingsCubit.getParameterValue(code);
-
-              final bool isSelected = (value == currentValue);
-
-              final double displayWidth = MediaQuery.of(context).size.width;
-              final double itemWidth = displayWidth / availableValues.length - 4;
-
-              return SizedBox.square(
-                dimension: itemWidth,
-                child: ParameterWidget(
-                  code: code,
-                  value: value,
-                  isSelected: isSelected,
-                  size: itemWidth,
-                  gameSettings: gameSettingsState.settings,
-                  globalSettings: globalSettingsState.settings,
-                  onPressed: () {
-                    isGlobal
-                        ? globalSettingsCubit.setParameterValue(code, value)
-                        : gameSettingsCubit.setParameterValue(code, value);
-                  },
-                ),
-              );
-            },
-          );
-        },
-      );
-
-      parameterButtons.add(parameterButton);
-    }
-
-    return parameterButtons;
-  }
-}
diff --git a/lib/ui/screens/page_game.dart b/lib/ui/screens/page_game.dart
deleted file mode 100644
index cdd15d84e52574ecb5ccbe1e3fc50aa924044590..0000000000000000000000000000000000000000
--- a/lib/ui/screens/page_game.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
-import 'package:sudoku/ui/layouts/game_layout.dart';
-import 'package:sudoku/ui/layouts/parameters_layout.dart';
-
-class PageGame extends StatelessWidget {
-  const PageGame({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
-
-        return currentGame.isRunning
-            ? const GameLayout()
-            : ParametersLayout(canResume: currentGame.canBeResumed);
-      },
-    );
-  }
-}
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index f235f48d501f7d2dd3a68d638cecbe6ea15acb32..49ca2e11f1ddc4abfa7e50823697e1ec5dec9fc7 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -1,34 +1,37 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/config/menu.dart';
-import 'package:sudoku/cubit/nav_cubit.dart';
-import 'package:sudoku/ui/widgets/global_app_bar.dart';
+import 'package:sudoku/common/config/activity_page.dart';
+import 'package:sudoku/common/config/screen.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_screens.dart';
+import 'package:sudoku/common/ui/nav/global_app_bar.dart';
+import 'package:sudoku/common/ui/nav/bottom_nav_bar.dart';
 
 class SkeletonScreen extends StatelessWidget {
   const SkeletonScreen({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      appBar: const GlobalAppBar(),
-      extendBodyBehindAppBar: false,
-      body: Material(
-        color: Theme.of(context).colorScheme.surface,
-        child: BlocBuilder<NavCubit, int>(
-          builder: (BuildContext context, int pageIndex) {
-            return Padding(
+    return BlocBuilder<NavCubitScreen, int>(
+      builder: (BuildContext context, int screenIndex) {
+        return Scaffold(
+          appBar: const GlobalAppBar(),
+          extendBodyBehindAppBar: false,
+          body: Material(
+            color: Theme.of(context).colorScheme.surface,
+            child: Padding(
               padding: const EdgeInsets.only(
                 top: 8,
                 left: 2,
                 right: 2,
               ),
-              child: Menu.getPageWidget(pageIndex),
-            );
-          },
-        ),
-      ),
-      backgroundColor: Theme.of(context).colorScheme.surface,
+              child: Screen.getWidget(screenIndex),
+            ),
+          ),
+          backgroundColor: Theme.of(context).colorScheme.surface,
+          bottomNavigationBar: ActivityPage.displayBottomNavBar ? const BottomNavBar() : null,
+        );
+      },
     );
   }
 }
diff --git a/lib/ui/widgets/actions/button_delete_saved_game.dart b/lib/ui/widgets/actions/button_delete_saved_game.dart
index dea6d4fa92efb3a66d54eeeef0e2b0b01d729747..5c63256abed88d04847d0fb0cd49c34982362499 100644
--- a/lib/ui/widgets/actions/button_delete_saved_game.dart
+++ b/lib/ui/widgets/actions/button_delete_saved_game.dart
@@ -1,7 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
 
 class DeleteSavedGameButton extends StatelessWidget {
   const DeleteSavedGameButton({super.key});
@@ -11,7 +11,7 @@ class DeleteSavedGameButton extends StatelessWidget {
     return StyledButton(
       color: Colors.grey,
       onPressed: () {
-        BlocProvider.of<GameCubit>(context).deleteSavedGame();
+        BlocProvider.of<ActivityCubit>(context).deleteSavedActivity();
       },
       child: const Image(
         image: AssetImage('assets/ui/button_delete_saved_game.png'),
diff --git a/lib/ui/widgets/actions/button_game_quit.dart b/lib/ui/widgets/actions/button_game_quit.dart
index 56d80c9e1c5f37faa5d44589e94bad2131a294ed..b32168826b8f79befa3dbe78f9caea9339fdbcbd 100644
--- a/lib/ui/widgets/actions/button_game_quit.dart
+++ b/lib/ui/widgets/actions/button_game_quit.dart
@@ -1,7 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_pages.dart';
+
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
 
 class QuitGameButton extends StatelessWidget {
   const QuitGameButton({super.key});
@@ -11,7 +13,8 @@ class QuitGameButton extends StatelessWidget {
     return StyledButton(
       color: Colors.red,
       onPressed: () {
-        BlocProvider.of<GameCubit>(context).quitGame();
+        BlocProvider.of<ActivityCubit>(context).quitActivity();
+        BlocProvider.of<NavCubitPage>(context).goToPageHome();
       },
       child: const Image(
         image: AssetImage('assets/ui/button_back.png'),
diff --git a/lib/ui/widgets/actions/button_game_start_new.dart b/lib/ui/widgets/actions/button_game_start_new.dart
index 87ecf843e23c373f14a91bb044e8da4e586e9132..295498db8421cd66cfa8f543f727aef74ae92782 100644
--- a/lib/ui/widgets/actions/button_game_start_new.dart
+++ b/lib/ui/widgets/actions/button_game_start_new.dart
@@ -1,26 +1,29 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/cubit/settings_game_cubit.dart';
-import 'package:sudoku/cubit/settings_global_cubit.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_pages.dart';
+
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/cubit/settings/settings_activity_cubit.dart';
+import 'package:sudoku/cubit/settings/settings_global_cubit.dart';
 
 class StartNewGameButton extends StatelessWidget {
   const StartNewGameButton({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameSettingsCubit, GameSettingsState>(
-      builder: (BuildContext context, GameSettingsState gameSettingsState) {
+    return BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
+      builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
         return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
           builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
             return StyledButton(
               color: Colors.blue,
               onPressed: () {
-                BlocProvider.of<GameCubit>(context).startNewGame(
-                  gameSettings: gameSettingsState.settings,
+                BlocProvider.of<ActivityCubit>(context).startNewActivity(
+                  activitySettings: activitySettingsState.settings,
                   globalSettings: globalSettingsState.settings,
                 );
+                BlocProvider.of<NavCubitPage>(context).goToPageGame();
               },
               child: const Image(
                 image: AssetImage('assets/ui/button_start.png'),
diff --git a/lib/ui/widgets/actions/button_resume_saved_game.dart b/lib/ui/widgets/actions/button_resume_saved_game.dart
index 3b45393a362cd63ed7d940aacf9f946c30e74580..301a1be4be2c46577c6525c749a33a4b413cdafe 100644
--- a/lib/ui/widgets/actions/button_resume_saved_game.dart
+++ b/lib/ui/widgets/actions/button_resume_saved_game.dart
@@ -1,7 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
+import 'package:sudoku/common/cubit/nav/nav_cubit_pages.dart';
+
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
 
 class ResumeSavedGameButton extends StatelessWidget {
   const ResumeSavedGameButton({super.key});
@@ -11,7 +13,8 @@ class ResumeSavedGameButton extends StatelessWidget {
     return StyledButton(
       color: Colors.blue,
       onPressed: () {
-        BlocProvider.of<GameCubit>(context).resumeSavedGame();
+        BlocProvider.of<ActivityCubit>(context).resumeSavedActivity();
+        BlocProvider.of<NavCubitPage>(context).goToPageGame();
       },
       child: const Image(
         image: AssetImage('assets/ui/button_resume_game.png'),
diff --git a/lib/ui/widgets/game/bar_select_cell_value.dart b/lib/ui/widgets/game/bar_select_cell_value.dart
index be62f999868173b3f393cbef8af68b5c7e0d9a8f..3ef348d14cd028588c45a5e9ffb8281b17a03b02 100644
--- a/lib/ui/widgets/game/bar_select_cell_value.dart
+++ b/lib/ui/widgets/game/bar_select_cell_value.dart
@@ -3,10 +3,10 @@ import 'dart:math';
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/cell.dart';
-import 'package:sudoku/models/game/cell_location.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/cell.dart';
+import 'package:sudoku/models/activity/cell_location.dart';
+import 'package:sudoku/models/activity/activity.dart';
 import 'package:sudoku/ui/widgets/game/cell_update.dart';
 
 class SelectCellValueBar extends StatelessWidget {
@@ -14,13 +14,13 @@ class SelectCellValueBar extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game game = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity activity = activityState.currentActivity;
 
         final bool isUpdatableCellSelected =
-            (game.selectedCell != null) ? !game.selectedCell!.isFixed : false;
-        final int maxValue = game.boardSize;
+            (activity.selectedCell != null) ? !activity.selectedCell!.isFixed : false;
+        final int maxValue = activity.boardSize;
 
         const int maxItemsPerLine = 10;
         final int linesCount = (maxValue / maxItemsPerLine).floor() + 1;
diff --git a/lib/ui/widgets/game/button_show_conflicts.dart b/lib/ui/widgets/game/button_show_conflicts.dart
index 0ba35cf38196892eeb74860135dd6867f891528e..58b0c24cf977ce4632a6109fb99d7e16f9b31c65 100644
--- a/lib/ui/widgets/game/button_show_conflicts.dart
+++ b/lib/ui/widgets/game/button_show_conflicts.dart
@@ -1,26 +1,26 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
 
 class ButtonShowConflicts extends StatelessWidget {
   const ButtonShowConflicts({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
 
         return StyledButton(
-          color: currentGame.showConflicts == true ? Colors.amber : Colors.grey,
+          color: currentActivity.showConflicts == true ? Colors.amber : Colors.grey,
           child: const Image(
             image: AssetImage('assets/ui/button_show_conflicts.png'),
             fit: BoxFit.fill,
           ),
           onPressed: () {
-            BlocProvider.of<GameCubit>(context).toggleShowConflicts();
+            BlocProvider.of<ActivityCubit>(context).toggleShowConflicts();
           },
         );
       },
diff --git a/lib/ui/widgets/game/button_show_tip.dart b/lib/ui/widgets/game/button_show_tip.dart
index 55dc9044a8c7e40f160b7a142eb1afcc23013bfb..57fcb25fae977313ae91b34973898aa2641bbb64 100644
--- a/lib/ui/widgets/game/button_show_tip.dart
+++ b/lib/ui/widgets/game/button_show_tip.dart
@@ -3,36 +3,38 @@ import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:sudoku/config/default_global_settings.dart';
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
 
 class ButtonShowTip extends StatelessWidget {
   const ButtonShowTip({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
 
         return StyledButton(
           color: Colors.purple,
           child: badges.Badge(
-            showBadge: currentGame.givenTipsCount == 0 ? false : true,
+            showBadge: currentActivity.givenTipsCount == 0 ? false : true,
             badgeStyle: badges.BadgeStyle(
-              badgeColor: currentGame.givenTipsCount < 10
+              badgeColor: currentActivity.givenTipsCount < 10
                   ? Colors.green
-                  : currentGame.givenTipsCount < 20
+                  : currentActivity.givenTipsCount < 20
                       ? Colors.orange
                       : Colors.red,
             ),
             badgeContent: Text(
-              currentGame.givenTipsCount == 0 ? '' : currentGame.givenTipsCount.toString(),
+              currentActivity.givenTipsCount == 0
+                  ? ''
+                  : currentActivity.givenTipsCount.toString(),
               style: const TextStyle(color: Colors.white),
             ),
             child: Container(
               padding: EdgeInsets.all(10 *
-                  currentGame.buttonTipsCountdown /
+                  currentActivity.buttonTipsCountdown /
                   DefaultGlobalSettings.defaultTipCountDownValueInSeconds),
               child: const Image(
                 image: AssetImage('assets/ui/button_help.png'),
@@ -41,8 +43,8 @@ class ButtonShowTip extends StatelessWidget {
             ),
           ),
           onPressed: () {
-            currentGame.canGiveTip
-                ? currentGame.showTip(BlocProvider.of<GameCubit>(context))
+            currentActivity.canGiveTip
+                ? currentActivity.showTip(BlocProvider.of<ActivityCubit>(context))
                 : null;
           },
         );
diff --git a/lib/ui/widgets/game/cell.dart b/lib/ui/widgets/game/cell.dart
index f85f9bbcfb8a45ea88e61c7199750736205b046f..3134f9f078ae4fda5adb0e8cc35d38ecd0eacbd5 100644
--- a/lib/ui/widgets/game/cell.dart
+++ b/lib/ui/widgets/game/cell.dart
@@ -1,9 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/cell.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/cell.dart';
+import 'package:sudoku/models/activity/activity.dart';
 
 class CellWidget extends StatelessWidget {
   const CellWidget({super.key, required this.cell});
@@ -12,16 +12,16 @@ class CellWidget extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game game = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity activity = activityState.currentActivity;
 
-        final String imageAsset = getImageAssetName(game);
+        final String imageAsset = getImageAssetName(activity);
 
         return Container(
           decoration: BoxDecoration(
-            color: getBackgroundColor(game),
-            border: getCellBorders(game),
+            color: getBackgroundColor(activity),
+            border: getCellBorders(activity),
           ),
           child: GestureDetector(
             child: AnimatedSwitcher(
@@ -36,13 +36,13 @@ class CellWidget extends StatelessWidget {
               ),
             ),
             onTap: () {
-              final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
+              final ActivityCubit activityCubit = BlocProvider.of<ActivityCubit>(context);
 
-              if (cell.location.col != game.selectedCell?.location.col ||
-                  cell.location.row != game.selectedCell?.location.row) {
-                gameCubit.selectCell(cell.location);
+              if (cell.location.col != activity.selectedCell?.location.col ||
+                  cell.location.row != activity.selectedCell?.location.row) {
+                activityCubit.selectCell(cell.location);
               } else {
-                gameCubit.unselectCell();
+                activityCubit.unselectCell();
               }
             },
           ),
@@ -54,17 +54,17 @@ class CellWidget extends StatelessWidget {
   /*
   * Compute image asset name, from skin and cell value/state
   */
-  String getImageAssetName(Game game) {
+  String getImageAssetName(Activity activity) {
     if ((cell.value) > 0) {
-      final int cellValue = game.getTranslatedValueForDisplay(cell.value);
-      return 'assets/skins/${game.globalSettings.skin}_$cellValue.png';
+      final int cellValue = activity.getTranslatedValueForDisplay(cell.value);
+      return 'assets/skins/${activity.globalSettings.skin}_$cellValue.png';
     }
 
     return 'assets/ui/cell_empty.png';
   }
 
   // Compute cell background color, from cell state
-  Color getBackgroundColor(Game game) {
+  Color getBackgroundColor(Activity activity) {
     final Color editableCellColor = Colors.grey.shade100;
     final Color editableCellColorConflict = Colors.pink.shade100;
     final Color fixedCellColor = Colors.grey.shade300;
@@ -80,9 +80,9 @@ class CellWidget extends StatelessWidget {
       backgroundColor = fixedCellColor;
     }
 
-    final int conflictsCount = game.boardConflicts[cell.location.row][cell.location.col];
+    final int conflictsCount = activity.boardConflicts[cell.location.row][cell.location.col];
 
-    if (game.showConflicts == true) {
+    if (activity.showConflicts == true) {
       if (conflictsCount != 0) {
         if (cell.isFixed == true) {
           backgroundColor = fixedCellColorConflict;
@@ -91,7 +91,7 @@ class CellWidget extends StatelessWidget {
         }
       }
 
-      if ((cell.value != 0) && (cell.value == game.selectedCell?.value)) {
+      if ((cell.value != 0) && (cell.value == activity.selectedCell?.value)) {
         if (cell.isFixed == true) {
           backgroundColor = fixedSelectedValueColor;
         } else {
@@ -100,7 +100,7 @@ class CellWidget extends StatelessWidget {
       }
     }
 
-    final bool isAnimated = game.boardAnimated[cell.location.row][cell.location.col];
+    final bool isAnimated = activity.boardAnimated[cell.location.row][cell.location.col];
 
     if (isAnimated) {
       if (cell.isFixed == true) {
@@ -114,7 +114,7 @@ class CellWidget extends StatelessWidget {
   }
 
   // Compute cell borders, from board size and cell state
-  Border getCellBorders(Game game) {
+  Border getCellBorders(Activity activity) {
     final Color cellBorderDarkColor = Colors.grey.shade800;
     final Color cellBorderLightColor = Colors.grey.shade600;
     const Color cellBorderSelectedColor = Colors.red;
@@ -123,14 +123,14 @@ class CellWidget extends StatelessWidget {
     double cellBorderWidth = 4;
 
     // Reduce cell border width on big boards
-    if (game.boardSize > 8) {
+    if (activity.boardSize > 8) {
       cellBorderWidth = 2;
-      if (game.boardSize > 10) {
+      if (activity.boardSize > 10) {
         cellBorderWidth = 1;
       }
     }
 
-    if (!game.isRunning) {
+    if (!activity.isRunning) {
       cellBorderColor = Colors.green.shade700;
     }
 
@@ -140,27 +140,27 @@ class CellWidget extends StatelessWidget {
     );
 
     // Update cell borders if not currently selected cell
-    if (cell.location.col != game.selectedCell?.location.col ||
-        cell.location.row != game.selectedCell?.location.row) {
+    if (cell.location.col != activity.selectedCell?.location.col ||
+        cell.location.row != activity.selectedCell?.location.row) {
       borders = Border(
         top: BorderSide(
             width: cellBorderWidth,
-            color: (((cell.location.row) % game.blockSizeVertical) == 0)
+            color: (((cell.location.row) % activity.blockSizeVertical) == 0)
                 ? cellBorderDarkColor
                 : cellBorderLightColor),
         left: BorderSide(
             width: cellBorderWidth,
-            color: (((cell.location.col) % game.blockSizeHorizontal) == 0)
+            color: (((cell.location.col) % activity.blockSizeHorizontal) == 0)
                 ? cellBorderDarkColor
                 : cellBorderLightColor),
         right: BorderSide(
             width: cellBorderWidth,
-            color: ((((cell.location.col) + 1) % game.blockSizeHorizontal) == 0)
+            color: ((((cell.location.col) + 1) % activity.blockSizeHorizontal) == 0)
                 ? cellBorderDarkColor
                 : cellBorderLightColor),
         bottom: BorderSide(
             width: cellBorderWidth,
-            color: ((((cell.location.row) + 1) % game.blockSizeVertical) == 0)
+            color: ((((cell.location.row) + 1) % activity.blockSizeVertical) == 0)
                 ? cellBorderDarkColor
                 : cellBorderLightColor),
       );
diff --git a/lib/ui/widgets/game/cell_update.dart b/lib/ui/widgets/game/cell_update.dart
index c4a09d41c6d5613d80762d3f9b2082cd2faa2a8c..e8182c932bc2c4fc2fc7d7b6827c77f2ff898ad6 100644
--- a/lib/ui/widgets/game/cell_update.dart
+++ b/lib/ui/widgets/game/cell_update.dart
@@ -1,9 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/cell.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/cell.dart';
+import 'package:sudoku/models/activity/activity.dart';
 
 class CellWidgetUpdate extends StatelessWidget {
   const CellWidgetUpdate({super.key, this.cell});
@@ -12,22 +12,23 @@ class CellWidgetUpdate extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game game = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity activity = activityState.currentActivity;
 
         if ((cell?.value ?? 0) < 0) {
           return Container();
         }
 
-        final String imageAsset = getImageAssetName(game);
+        final String imageAsset = getImageAssetName(activity);
 
         Color backgroundColor = Colors.grey.shade200;
 
-        if (game.showConflicts == true &&
-            game.selectedCell?.location.col != null &&
-            game.selectedCell?.location.row != null) {
-          if (!game.board.isValueAllowed(game.selectedCell?.location, cell?.value ?? 0)) {
+        if (activity.showConflicts == true &&
+            activity.selectedCell?.location.col != null &&
+            activity.selectedCell?.location.row != null) {
+          if (!activity.board
+              .isValueAllowed(activity.selectedCell?.location, cell?.value ?? 0)) {
             backgroundColor = Colors.pink.shade100;
           }
         }
@@ -43,13 +44,14 @@ class CellWidgetUpdate extends StatelessWidget {
           child: GestureDetector(
             child: Image(image: AssetImage(imageAsset), fit: BoxFit.fill),
             onTap: () {
-              final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
+              final ActivityCubit activityCubit = BlocProvider.of<ActivityCubit>(context);
 
-              if (game.selectedCell != null) {
-                gameCubit.updateCellValue(game.selectedCell!.location, cell?.value ?? 0);
+              if (activity.selectedCell != null) {
+                activityCubit.updateCellValue(
+                    activity.selectedCell!.location, cell?.value ?? 0);
               }
 
-              gameCubit.unselectCell();
+              activityCubit.unselectCell();
             },
           ),
         );
@@ -60,10 +62,10 @@ class CellWidgetUpdate extends StatelessWidget {
   /*
   * Compute image asset name, from skin and cell value/state
   */
-  String getImageAssetName(Game game) {
+  String getImageAssetName(Activity activity) {
     if ((cell?.value ?? 0) > 0) {
-      final int cellValue = game.getTranslatedValueForDisplay(cell?.value ?? 0);
-      return 'assets/skins/${game.globalSettings.skin}_$cellValue.png';
+      final int cellValue = activity.getTranslatedValueForDisplay(cell?.value ?? 0);
+      return 'assets/skins/${activity.globalSettings.skin}_$cellValue.png';
     }
 
     return 'assets/ui/cell_empty.png';
diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart
index de98e555986df1a8255d277c93437e6a67402900..898137e9d19d517e141335ddb60bfde56744ac36 100644
--- a/lib/ui/widgets/game/game_board.dart
+++ b/lib/ui/widgets/game/game_board.dart
@@ -1,9 +1,9 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/cell_location.dart';
-import 'package:sudoku/models/game/game.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/cell_location.dart';
+import 'package:sudoku/models/activity/activity.dart';
 import 'package:sudoku/ui/widgets/game/cell.dart';
 
 class GameBoardWidget extends StatelessWidget {
@@ -11,9 +11,9 @@ class GameBoardWidget extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
 
         final Color borderColor = Theme.of(context).colorScheme.onSurface;
 
@@ -33,14 +33,14 @@ class GameBoardWidget extends StatelessWidget {
               Table(
                 defaultColumnWidth: const IntrinsicColumnWidth(),
                 children: [
-                  for (int row = 0; row < currentGame.boardSize; row++)
+                  for (int row = 0; row < currentActivity.boardSize; row++)
                     TableRow(
                       children: [
-                        for (int col = 0; col < currentGame.boardSize; col++)
+                        for (int col = 0; col < currentActivity.boardSize; col++)
                           Column(
                             children: [
                               CellWidget(
-                                  cell: currentGame.board.get(CellLocation.go(row, col)))
+                                  cell: currentActivity.board.get(CellLocation.go(row, col)))
                             ],
                           ),
                       ],
diff --git a/lib/utils/board_animate.dart b/lib/utils/board_animate.dart
index a1a5239e36ad49e7a7dc2e3fc7057239c3ec7c60..9a7d5663e4397b00cf44b995b5b68888915ab542 100644
--- a/lib/utils/board_animate.dart
+++ b/lib/utils/board_animate.dart
@@ -1,21 +1,21 @@
 import 'dart:async';
 
-import 'package:sudoku/cubit/game_cubit.dart';
-import 'package:sudoku/models/game/game.dart';
-import 'package:sudoku/models/game/types.dart';
+import 'package:sudoku/cubit/activity/activity_cubit.dart';
+import 'package:sudoku/models/activity/activity.dart';
+import 'package:sudoku/models/activity/types.dart';
 
 class BoardAnimate {
   // Start game animation: blinking tiles
-  static AnimatedBoardSequence createStartGameAnimationPatterns(Game game) {
+  static AnimatedBoardSequence createStartGameAnimationPatterns(Activity activity) {
     AnimatedBoardSequence patterns = [];
 
     int patternsCount = 3;
 
     for (int patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
       AnimatedBoard pattern = [];
-      for (int row = 0; row < game.boardSize; row++) {
+      for (int row = 0; row < activity.boardSize; row++) {
         List<bool> patternRow = [];
-        for (int col = 0; col < game.boardSize; col++) {
+        for (int col = 0; col < activity.boardSize; col++) {
           patternRow.add(((patternIndex + row + col) % 2 == 0));
         }
         pattern.add(patternRow);
@@ -27,16 +27,16 @@ class BoardAnimate {
   }
 
   // Win game animation: fill board with colored rows, from bottom to top
-  static AnimatedBoardSequence createWinGameAnimationPatterns(Game game) {
+  static AnimatedBoardSequence createWinGameAnimationPatterns(Activity activity) {
     AnimatedBoardSequence patterns = [];
 
-    int patternsCount = game.boardSize + 6;
+    int patternsCount = activity.boardSize + 6;
 
     for (int patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
       AnimatedBoard pattern = [];
-      for (int row = 0; row < game.boardSize; row++) {
+      for (int row = 0; row < activity.boardSize; row++) {
         List<bool> patternRow = [];
-        for (int col = 0; col < game.boardSize; col++) {
+        for (int col = 0; col < activity.boardSize; col++) {
           patternRow.add(row > (patternIndex - 4));
         }
         pattern.add(patternRow);
@@ -48,17 +48,17 @@ class BoardAnimate {
   }
 
   // Default multi-purpose animation: sliding stripes, from top left to right bottom
-  static AnimatedBoardSequence createDefaultAnimationPatterns(Game game) {
+  static AnimatedBoardSequence createDefaultAnimationPatterns(Activity activity) {
     AnimatedBoardSequence patterns = [];
 
-    int boardSideLength = game.boardSize;
+    int boardSideLength = activity.boardSize;
     int patternsCount = boardSideLength;
 
     for (int patternIndex = 0; patternIndex < patternsCount; patternIndex++) {
       AnimatedBoard pattern = [];
-      for (int row = 0; row < game.boardSize; row++) {
+      for (int row = 0; row < activity.boardSize; row++) {
         List<bool> patternRow = [];
-        for (int col = 0; col < game.boardSize; col++) {
+        for (int col = 0; col < activity.boardSize; col++) {
           patternRow.add(((patternIndex + row + col) % 4 == 0));
         }
         pattern.add(patternRow);
@@ -69,25 +69,25 @@ class BoardAnimate {
     return patterns;
   }
 
-  static void startAnimation(GameCubit gameCubit, String animationType) {
-    final Game game = gameCubit.state.currentGame;
+  static void startAnimation(ActivityCubit activityCubit, String animationType) {
+    final Activity activity = activityCubit.state.currentActivity;
 
     AnimatedBoardSequence patterns = [];
 
     switch (animationType) {
       case 'start':
-        patterns = createStartGameAnimationPatterns(game);
+        patterns = createStartGameAnimationPatterns(activity);
         break;
       case 'win':
-        patterns = createWinGameAnimationPatterns(game);
+        patterns = createWinGameAnimationPatterns(activity);
         break;
       default:
-        patterns = createDefaultAnimationPatterns(game);
+        patterns = createDefaultAnimationPatterns(activity);
     }
 
     int patternIndex = patterns.length;
 
-    gameCubit.updateAnimationInProgress(true);
+    activityCubit.updateAnimationInProgress(true);
 
     const interval = Duration(milliseconds: 200);
     Timer.periodic(
@@ -95,11 +95,11 @@ class BoardAnimate {
       (Timer timer) {
         if (patternIndex == 0) {
           timer.cancel();
-          gameCubit.resetAnimatedBackground();
-          gameCubit.updateAnimationInProgress(false);
+          activityCubit.resetAnimatedBackground();
+          activityCubit.updateAnimationInProgress(false);
         } else {
           patternIndex--;
-          gameCubit.setAnimatedBackground(patterns[patternIndex]);
+          activityCubit.setAnimatedBackground(patterns[patternIndex]);
         }
       },
     );
diff --git a/pubspec.lock b/pubspec.lock
index cd1c7bb2bf3a8cb1b5fe1009f6f02e40355504dc..0604c290af2b37704e236c57993de7982d4d5650 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -253,10 +253,10 @@ packages:
     dependency: transitive
     description:
       name: path_provider
-      sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
+      sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.4"
+    version: "2.1.5"
   path_provider_android:
     dependency: transitive
     description:
@@ -450,10 +450,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: "2735daae5150e8b1dfeb3eb0544b4d3af0061e9e82cef063adcd583bdae4306a"
+      sha256: "10169d3934549017f0ae278ccb07f828f9d6ea21573bab0fb77b0e1ef0fce454"
       url: "https://pub.dev"
     source: hosted
-    version: "5.7.0"
+    version: "5.7.2"
   xdg_directories:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index fa691706f6b4791a7e8de865f2b74dccf7acc9b5..dd80ac47002bd0cd746ac96f9990ce944cabcbdd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: A sudoku game application.
 
 publish_to: "none"
 
-version: 0.4.1+77
+version: 0.5.0+78
 
 environment:
   sdk: "^3.0.0"