From c23f7fb7d1d58f8ffdac0ac1dbbbbcb30c4c791e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Wed, 15 May 2024 16:49:55 +0200
Subject: [PATCH] Normalize game architecture

---
 android/gradle.properties                     |   4 +-
 assets/translations/en.json                   |   6 +-
 assets/translations/fr.json                   |   6 +-
 assets/{icons => ui}/button_back.png          | Bin
 assets/ui/button_delete_saved_game.png        | Bin 0 -> 5813 bytes
 assets/ui/button_resume_game.png              | Bin 0 -> 3659 bytes
 assets/{icons => ui}/button_start.png         | Bin
 assets/ui/game_end.png                        | Bin 0 -> 7937 bytes
 assets/{icons => ui}/placeholder.png          | Bin
 .../metadata/android/en-US/changelogs/40.txt  |   1 +
 .../metadata/android/fr-FR/changelogs/40.txt  |   1 +
 icons/build_game_icons.sh                     |  78 -----------
 lib/config/default_game_settings.dart         |  58 +++++---
 lib/config/default_global_settings.dart       |  27 +++-
 lib/config/menu.dart                          |   5 -
 lib/config/theme.dart                         |  10 +-
 lib/cubit/game_cubit.dart                     |  44 ++++--
 lib/cubit/game_state.dart                     |   2 +-
 lib/cubit/settings_game_cubit.dart            |  38 +++---
 lib/cubit/settings_game_state.dart            |   4 -
 lib/cubit/settings_global_cubit.dart          |  42 ++++--
 lib/cubit/settings_global_state.dart          |   4 -
 lib/data/fetch_data_helper.dart               |   2 +-
 lib/main.dart                                 |  48 +++++--
 lib/models/game.dart                          | 100 --------------
 lib/models/game/game.dart                     | 125 ++++++++++++++++++
 lib/models/{data => game}/game_item.dart      |   0
 lib/models/{ => settings}/settings_game.dart  |  22 +--
 lib/models/settings/settings_global.dart      |  41 ++++++
 lib/models/settings_global.dart               |  23 ----
 lib/ui/game/game_end.dart                     |  57 ++++++++
 lib/ui/game/game_top.dart                     |  23 ++++
 lib/ui/helpers/app_titles.dart                |  32 +++++
 .../helpers/outlined_text_widget.dart         |   0
 lib/ui/layouts/game_layout.dart               |  38 ++++++
 .../parameters_layout.dart}                   |  83 +++++++++---
 lib/ui/parameters/parameter_image.dart        |  38 ++++++
 .../parameter_painter.dart                    |  28 ++--
 lib/ui/screens/page_about.dart                |  52 ++++----
 lib/ui/screens/page_game.dart                 |  16 ++-
 lib/ui/screens/page_settings.dart             |  26 ++--
 .../{widgets => }/settings/settings_form.dart |   2 +-
 lib/ui/{widgets => }/settings/theme_card.dart |   0
 lib/ui/skeleton.dart                          |   4 +-
 .../actions/button_delete_saved_game.dart     |  21 +++
 lib/ui/widgets/actions/button_game_quit.dart  |  21 +++
 .../{ => actions}/button_game_start_new.dart  |  14 +-
 .../actions/button_resume_saved_game.dart     |  21 +++
 lib/ui/widgets/game/game.dart                 |  37 ------
 lib/ui/widgets/game/game_board.dart           |  22 +++
 lib/ui/widgets/game/game_countdown.dart       |   4 +-
 .../widgets/game/game_position_indicator.dart |   6 +-
 lib/ui/widgets/game/widget_category.dart      |   5 +-
 lib/ui/widgets/game/widget_letter.dart        |   7 +-
 lib/ui/widgets/global_app_bar.dart            |  13 +-
 lib/ui/widgets/helpers/app_header.dart        |  24 ----
 lib/ui/widgets/helpers/app_title.dart         |  17 ---
 pubspec.lock                                  |  32 ++---
 pubspec.yaml                                  |   9 +-
 .../app/build_application_resources.sh        |   2 +-
 {icons => resources/app}/featureGraphic.svg   |   0
 {icons => resources/app}/icon.svg             |   0
 resources/build_resources.sh                  |   8 ++
 .../data}/build_categories_list.sh            |   2 +-
 {scripts => resources/data}/categories.csv    |   0
 resources/ui/build_ui_resources.sh            | 110 +++++++++++++++
 .../ui/images}/button_back.svg                |   0
 .../ui/images/button_delete_saved_game.svg    |   2 +
 resources/ui/images/button_resume_game.svg    |   2 +
 .../ui/images}/button_start.svg               |   0
 resources/ui/images/game_end.svg              |   2 +
 .../ui/images}/placeholder.svg                |   0
 72 files changed, 947 insertions(+), 524 deletions(-)
 rename assets/{icons => ui}/button_back.png (100%)
 create mode 100644 assets/ui/button_delete_saved_game.png
 create mode 100644 assets/ui/button_resume_game.png
 rename assets/{icons => ui}/button_start.png (100%)
 create mode 100644 assets/ui/game_end.png
 rename assets/{icons => ui}/placeholder.png (100%)
 create mode 100644 fastlane/metadata/android/en-US/changelogs/40.txt
 create mode 100644 fastlane/metadata/android/fr-FR/changelogs/40.txt
 delete mode 100755 icons/build_game_icons.sh
 delete mode 100644 lib/models/game.dart
 create mode 100644 lib/models/game/game.dart
 rename lib/models/{data => game}/game_item.dart (100%)
 rename lib/models/{ => settings}/settings_game.dart (57%)
 create mode 100644 lib/models/settings/settings_global.dart
 delete mode 100644 lib/models/settings_global.dart
 create mode 100644 lib/ui/game/game_end.dart
 create mode 100644 lib/ui/game/game_top.dart
 create mode 100644 lib/ui/helpers/app_titles.dart
 rename lib/ui/{widgets => }/helpers/outlined_text_widget.dart (100%)
 create mode 100644 lib/ui/layouts/game_layout.dart
 rename lib/ui/{widgets/parameters.dart => layouts/parameters_layout.dart} (52%)
 create mode 100644 lib/ui/parameters/parameter_image.dart
 rename lib/ui/{painters => parameters}/parameter_painter.dart (87%)
 rename lib/ui/{widgets => }/settings/settings_form.dart (96%)
 rename lib/ui/{widgets => }/settings/theme_card.dart (100%)
 create mode 100644 lib/ui/widgets/actions/button_delete_saved_game.dart
 create mode 100644 lib/ui/widgets/actions/button_game_quit.dart
 rename lib/ui/widgets/{ => actions}/button_game_start_new.dart (72%)
 create mode 100644 lib/ui/widgets/actions/button_resume_saved_game.dart
 delete mode 100644 lib/ui/widgets/game/game.dart
 create mode 100644 lib/ui/widgets/game/game_board.dart
 delete mode 100644 lib/ui/widgets/helpers/app_header.dart
 delete mode 100644 lib/ui/widgets/helpers/app_title.dart
 rename icons/build_application_icons.sh => resources/app/build_application_resources.sh (98%)
 rename {icons => resources/app}/featureGraphic.svg (100%)
 rename {icons => resources/app}/icon.svg (100%)
 create mode 100755 resources/build_resources.sh
 rename {scripts => resources/data}/build_categories_list.sh (98%)
 rename {scripts => resources/data}/categories.csv (100%)
 create mode 100755 resources/ui/build_ui_resources.sh
 rename {icons => resources/ui/images}/button_back.svg (100%)
 create mode 100644 resources/ui/images/button_delete_saved_game.svg
 create mode 100644 resources/ui/images/button_resume_game.svg
 rename {icons => resources/ui/images}/button_start.svg (100%)
 create mode 100644 resources/ui/images/game_end.svg
 rename {icons => resources/ui/images}/placeholder.svg (100%)

diff --git a/android/gradle.properties b/android/gradle.properties
index 665a788..e3b4d8a 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
 android.useAndroidX=true
 android.enableJetifier=true
-app.versionName=1.2.33
-app.versionCode=39
+app.versionName=1.3.0
+app.versionCode=40
diff --git a/assets/translations/en.json b/assets/translations/en.json
index d7aedb9..393e6ef 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -1,12 +1,8 @@
 {
   "app_name": "Categories",
 
-  "bottom_nav_home": "Game",
-  "bottom_nav_settings": "Settings",
-  "bottom_nav_about": "About",
-
   "settings_title": "Settings",
-  "settings_label_theme":"Theme mode",
+  "settings_label_theme": "Theme mode",
 
   "about_title": "Informations",
   "about_content": "Categories",
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
index d40e253..3088da5 100644
--- a/assets/translations/fr.json
+++ b/assets/translations/fr.json
@@ -1,12 +1,8 @@
 {
   "app_name": "Petit Bac",
 
-  "bottom_nav_home": "Jeu",
-  "bottom_nav_settings": "Réglages",
-  "bottom_nav_about": "Infos",
-
   "settings_title": "Réglages",
-  "settings_label_theme":"Thème de couleurs",
+  "settings_label_theme": "Thème de couleurs",
 
   "about_title": "Informations",
   "about_content": "Petit Bac.",
diff --git a/assets/icons/button_back.png b/assets/ui/button_back.png
similarity index 100%
rename from assets/icons/button_back.png
rename to assets/ui/button_back.png
diff --git a/assets/ui/button_delete_saved_game.png b/assets/ui/button_delete_saved_game.png
new file mode 100644
index 0000000000000000000000000000000000000000..5e4f217689b11e444b7163557d7e5d68f3bbfe7d
GIT binary patch
literal 5813
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

literal 0
HcmV?d00001

diff --git a/assets/ui/button_resume_game.png b/assets/ui/button_resume_game.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2ea0a02d05e42377eb551a4b51428b511a32f5d
GIT binary patch
literal 3659
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

literal 0
HcmV?d00001

diff --git a/assets/icons/button_start.png b/assets/ui/button_start.png
similarity index 100%
rename from assets/icons/button_start.png
rename to assets/ui/button_start.png
diff --git a/assets/ui/game_end.png b/assets/ui/game_end.png
new file mode 100644
index 0000000000000000000000000000000000000000..876334279c1711b349a62131a33607eecf924eb6
GIT binary patch
literal 7937
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
P3=9mOu6{1-oD!M<Ur^e&

literal 0
HcmV?d00001

diff --git a/assets/icons/placeholder.png b/assets/ui/placeholder.png
similarity index 100%
rename from assets/icons/placeholder.png
rename to assets/ui/placeholder.png
diff --git a/fastlane/metadata/android/en-US/changelogs/40.txt b/fastlane/metadata/android/en-US/changelogs/40.txt
new file mode 100644
index 0000000..d4afd51
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40.txt
@@ -0,0 +1 @@
+Improve/normalize game architecture.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/40.txt b/fastlane/metadata/android/fr-FR/changelogs/40.txt
new file mode 100644
index 0000000..6a9871a
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/40.txt
@@ -0,0 +1 @@
+Amélioration/normalisation de l'architecture du jeu.
diff --git a/icons/build_game_icons.sh b/icons/build_game_icons.sh
deleted file mode 100755
index 7368dc4..0000000
--- a/icons/build_game_icons.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#! /bin/bash
-
-# Check dependencies
-command -v inkscape >/dev/null 2>&1 || { echo >&2 "I require inkscape but it's not installed. Aborting."; exit 1; }
-command -v scour >/dev/null 2>&1 || { echo >&2 "I require scour but it's not installed. Aborting."; exit 1; }
-command -v optipng >/dev/null 2>&1 || { echo >&2 "I require optipng but it's not installed. Aborting."; exit 1; }
-
-CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
-BASE_DIR="$(dirname "${CURRENT_DIR}")"
-ASSETS_DIR="${BASE_DIR}/assets"
-
-OPTIPNG_OPTIONS="-preserve -quiet -o7"
-ICON_SIZE=192
-
-#######################################################
-
-# Game images
-AVAILABLE_GAME_IMAGES="
-  button_back
-  button_start
-  placeholder
-"
-
-#######################################################
-
-# optimize svg
-function optimize_svg() {
-  SOURCE="$1"
-
-  cp ${SOURCE} ${SOURCE}.tmp
-  scour \
-      --remove-descriptive-elements \
-      --enable-id-stripping \
-      --enable-viewboxing \
-      --enable-comment-stripping \
-      --nindent=4 \
-      --quiet \
-      -i ${SOURCE}.tmp \
-      -o ${SOURCE}
-  rm ${SOURCE}.tmp
-}
-
-# build icons
-function build_icon() {
-  SOURCE="$1"
-  TARGET="$2"
-
-  echo "Building ${TARGET}"
-
-  if [ ! -f "${SOURCE}" ]; then
-    echo "Missing file: ${SOURCE}"
-    exit 1
-  fi
-
-  optimize_svg "${SOURCE}"
-
-  inkscape \
-      --export-width=${ICON_SIZE} \
-      --export-height=${ICON_SIZE} \
-      --export-filename=${TARGET} \
-      ${SOURCE}
-
-  optipng ${OPTIPNG_OPTIONS} ${TARGET}
-}
-
-#######################################################
-
-# Create output folders
-mkdir -p ${ASSETS_DIR}/icons
-
-# Delete existing generated images
-find ${ASSETS_DIR}/icons -type f -name "*.png" -delete
-
-# build game images
-for GAME_IMAGE in ${AVAILABLE_GAME_IMAGES}
-do
-  build_icon ${CURRENT_DIR}/${GAME_IMAGE}.svg ${ASSETS_DIR}/icons/${GAME_IMAGE}.png
-done
diff --git a/lib/config/default_game_settings.dart b/lib/config/default_game_settings.dart
index a1556ef..68fbb4e 100644
--- a/lib/config/default_game_settings.dart
+++ b/lib/config/default_game_settings.dart
@@ -10,42 +10,70 @@ class DefaultGameSettings {
   ];
 
   // items count: available values
-  static const int itemsCountValueNoLimit = 0;
-  static const int itemsCountValueShort = 5;
-  static const int itemsCountValueMedium = 10;
-  static const int itemsCountValueLong = 20;
-  static const List<int> allowedItemsCountValues = [
+  static const String itemsCountValueNoLimit = 'nolimit';
+  static const String itemsCountValueShort = 'short';
+  static const String itemsCountValueMedium = 'medium';
+  static const String itemsCountValueLong = 'long';
+  static const List<String> allowedItemsCountValues = [
     itemsCountValueNoLimit,
     itemsCountValueShort,
     itemsCountValueMedium,
     itemsCountValueLong,
   ];
   // items count: default value
-  static const int defaultItemsCountValue = itemsCountValueMedium;
+  static const String defaultItemsCountValue = itemsCountValueMedium;
 
   // timer value: available values
-  static const int timerValueNoTimer = 0;
-  static const int timerValueLow = 10;
-  static const int timerValueMedium = 30;
-  static const int timerValueHigh = 60;
-  static const List<int> allowedTimerValues = [
+  static const String timerValueNoTimer = 'nolimit';
+  static const String timerValueLow = 'low';
+  static const String timerValueMedium = 'medium';
+  static const String timerValueHigh = 'high';
+  static const List<String> allowedTimerValues = [
     timerValueNoTimer,
     timerValueLow,
     timerValueMedium,
     timerValueHigh,
   ];
   // timer value: default value
-  static const int defaultTimerValue = timerValueMedium;
+  static const String defaultTimerValue = timerValueMedium;
 
-  static List<int> getAvailableValues(String parameterCode) {
+  // available values from parameter code
+  static List<String> getAvailableValues(String parameterCode) {
     switch (parameterCode) {
-      case 'itemsCount':
+      case parameterCodeItemsCount:
         return DefaultGameSettings.allowedItemsCountValues;
-      case 'timerValue':
+      case parameterCodeTimerValue:
         return DefaultGameSettings.allowedTimerValues;
     }
 
     printlog('Did not find any available value for game parameter "$parameterCode".');
     return [];
   }
+
+  static int getItemsCountValueFromCode(String itemsCountParameterValue) {
+    const Map<String, int> values = {
+      DefaultGameSettings.itemsCountValueNoLimit: 0,
+      DefaultGameSettings.itemsCountValueShort: 5,
+      DefaultGameSettings.itemsCountValueMedium: 10,
+      DefaultGameSettings.itemsCountValueLong: 20,
+    };
+    return values[itemsCountParameterValue] ??
+        getItemsCountValueFromCode(DefaultGameSettings.defaultItemsCountValue);
+  }
+
+  static int getTimerValueFromCode(String timerValueParameterValue) {
+    const Map<String, int> values = {
+      timerValueNoTimer: 0,
+      timerValueLow: 5,
+      timerValueMedium: 30,
+      timerValueHigh: 90,
+    };
+    return values[timerValueParameterValue] ??
+        getTimerValueFromCode(DefaultGameSettings.defaultTimerValue);
+  }
+
+  // parameters displayed with assets (instead of painter)
+  static List<String> displayedWithAssets = [
+    //
+  ];
 }
diff --git a/lib/config/default_global_settings.dart b/lib/config/default_global_settings.dart
index 363c2a1..5201cc6 100644
--- a/lib/config/default_global_settings.dart
+++ b/lib/config/default_global_settings.dart
@@ -1,10 +1,33 @@
 import 'package:petitbac/utils/tools.dart';
 
 class DefaultGlobalSettings {
-  static const List<String> availableParameters = [];
+  // available global parameters codes
+  static const String parameterCodeSkin = 'skin';
+  static const List<String> availableParameters = [
+    parameterCodeSkin,
+  ];
+
+  // skin: available values
+  static const String skinValueDefault = 'default';
+  static const List<String> allowedSkinValues = [
+    skinValueDefault,
+  ];
+  // skin: default value
+  static const String defaultSkinValue = skinValueDefault;
+
+  // available values from parameter code
+  static List<String> getAvailableValues(String parameterCode) {
+    switch (parameterCode) {
+      case parameterCodeSkin:
+        return DefaultGlobalSettings.allowedSkinValues;
+    }
 
-  static List<int> getAvailableValues(String parameterCode) {
     printlog('Did not find any available value for global parameter "$parameterCode".');
     return [];
   }
+
+  // parameters displayed with assets (instead of painter)
+  static List<String> displayedWithAssets = [
+    //
+  ];
 }
diff --git a/lib/config/menu.dart b/lib/config/menu.dart
index d875b6b..437003f 100644
--- a/lib/config/menu.dart
+++ b/lib/config/menu.dart
@@ -6,12 +6,10 @@ import 'package:petitbac/ui/screens/page_game.dart';
 import 'package:petitbac/ui/screens/page_settings.dart';
 
 class MenuItem {
-  final String code;
   final Icon icon;
   final Widget page;
 
   const MenuItem({
-    required this.code,
     required this.icon,
     required this.page,
   });
@@ -20,21 +18,18 @@ class MenuItem {
 class Menu {
   static const indexGame = 0;
   static const menuItemGame = MenuItem(
-    code: 'bottom_nav_game',
     icon: Icon(UniconsLine.home),
     page: PageGame(),
   );
 
   static const indexSettings = 1;
   static const menuItemSettings = MenuItem(
-    code: 'bottom_nav_settings',
     icon: Icon(UniconsLine.setting),
     page: PageSettings(),
   );
 
   static const indexAbout = 2;
   static const menuItemAbout = MenuItem(
-    code: 'bottom_nav_about',
     icon: Icon(UniconsLine.info_circle),
     page: PageAbout(),
   );
diff --git a/lib/config/theme.dart b/lib/config/theme.dart
index be39034..74f532f 100644
--- a/lib/config/theme.dart
+++ b/lib/config/theme.dart
@@ -39,11 +39,9 @@ final ColorScheme lightColorScheme = ColorScheme.light(
   secondary: primarySwatch.shade500,
   onSecondary: Colors.white,
   error: errorColor,
-  background: textSwatch.shade200,
-  onBackground: textSwatch.shade500,
   onSurface: textSwatch.shade500,
   surface: textSwatch.shade50,
-  surfaceVariant: Colors.white,
+  surfaceContainerHighest: Colors.white,
   shadow: textSwatch.shade900.withOpacity(.1),
 );
 
@@ -52,11 +50,9 @@ final ColorScheme darkColorScheme = ColorScheme.dark(
   secondary: primarySwatch.shade500,
   onSecondary: Colors.white,
   error: errorColor,
-  background: const Color(0xFF171724),
-  onBackground: textSwatch.shade400,
   onSurface: textSwatch.shade300,
   surface: const Color(0xFF262630),
-  surfaceVariant: const Color(0xFF282832),
+  surfaceContainerHighest: const Color(0xFF282832),
   shadow: textSwatch.shade900.withOpacity(.2),
 );
 
@@ -192,5 +188,3 @@ final ThemeData darkTheme = lightTheme.copyWith(
     ),
   ),
 );
-
-final ThemeData appTheme = darkTheme;
diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart
index d310d36..13f7460 100644
--- a/lib/cubit/game_cubit.dart
+++ b/lib/cubit/game_cubit.dart
@@ -6,17 +6,17 @@ import 'package:flutter/material.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 import 'package:petitbac/data/fetch_data_helper.dart';
-import 'package:petitbac/models/data/game_item.dart';
-import 'package:petitbac/models/game.dart';
-import 'package:petitbac/models/settings_game.dart';
-import 'package:petitbac/models/settings_global.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/models/game/game_item.dart';
+import 'package:petitbac/models/settings/settings_game.dart';
+import 'package:petitbac/models/settings/settings_global.dart';
 
 part 'game_state.dart';
 
 class GameCubit extends HydratedCubit<GameState> {
   GameCubit()
       : super(GameState(
-          currentGame: Game.createNull(),
+          currentGame: Game.createEmpty(),
         ));
 
   void updateState(Game game) {
@@ -27,13 +27,19 @@ class GameCubit extends HydratedCubit<GameState> {
 
   void refresh() {
     final Game game = Game(
+      // Settings
       gameSettings: state.currentGame.gameSettings,
       globalSettings: state.currentGame.globalSettings,
-      items: state.currentGame.items,
+      // State
       isRunning: state.currentGame.isRunning,
+      isStarted: state.currentGame.isStarted,
       isFinished: state.currentGame.isFinished,
-      countdown: state.currentGame.countdown,
+      animationInProgress: state.currentGame.animationInProgress,
+      // Base data
+      items: state.currentGame.items,
+      // Game data
       position: state.currentGame.position,
+      countdown: state.currentGame.countdown,
     );
     // game.dump();
 
@@ -44,7 +50,8 @@ class GameCubit extends HydratedCubit<GameState> {
     required GameSettings gameSettings,
     required GlobalSettings globalSettings,
   }) {
-    Game newGame = Game.createNew(
+    final Game newGame = Game.createNew(
+      // Settings
       gameSettings: gameSettings,
       globalSettings: globalSettings,
     );
@@ -60,8 +67,19 @@ class GameCubit extends HydratedCubit<GameState> {
     refresh();
   }
 
+  void resumeSavedGame() {
+    state.currentGame.isRunning = true;
+    refresh();
+  }
+
+  void deleteSavedGame() {
+    state.currentGame.isRunning = false;
+    state.currentGame.isFinished = true;
+    refresh();
+  }
+
   void next() {
-    if (state.currentGame.position < (state.currentGame.gameSettings.itemsCount - 1)) {
+    if (state.currentGame.position < (state.currentGame.gameSettings.itemsCountValue - 1)) {
       state.currentGame.position++;
       startTimer();
     } else {
@@ -71,7 +89,7 @@ class GameCubit extends HydratedCubit<GameState> {
   }
 
   void startTimer() {
-    int timerValue = state.currentGame.gameSettings.timerValue;
+    int timerValue = state.currentGame.gameSettings.timerCountValue;
 
     if (timerValue != 0) {
       state.currentGame.countdown = timerValue;
@@ -88,7 +106,7 @@ class GameCubit extends HydratedCubit<GameState> {
           if (state.currentGame.countdown == 0) {
             timer.cancel();
             if (state.currentGame.position ==
-                (state.currentGame.gameSettings.itemsCount - 1)) {
+                (state.currentGame.gameSettings.itemsCountValue - 1)) {
               state.currentGame.isFinished = true;
             }
           }
@@ -97,7 +115,7 @@ class GameCubit extends HydratedCubit<GameState> {
         },
       );
     } else {
-      if (state.currentGame.position == (state.currentGame.gameSettings.itemsCount - 1)) {
+      if (state.currentGame.position == (state.currentGame.gameSettings.itemsCountValue - 1)) {
         state.currentGame.isFinished = true;
       }
     }
@@ -132,7 +150,7 @@ class GameCubit extends HydratedCubit<GameState> {
 
   @override
   GameState? fromJson(Map<String, dynamic> json) {
-    Game currentGame = json['currentGame'] as Game;
+    final Game currentGame = json['currentGame'] as Game;
 
     return GameState(
       currentGame: currentGame,
diff --git a/lib/cubit/game_state.dart b/lib/cubit/game_state.dart
index 8581d72..00e2116 100644
--- a/lib/cubit/game_state.dart
+++ b/lib/cubit/game_state.dart
@@ -9,7 +9,7 @@ class GameState extends Equatable {
   final Game currentGame;
 
   @override
-  List<Object?> get props => <Object?>[
+  List<dynamic> get props => <dynamic>[
         currentGame,
       ];
 }
diff --git a/lib/cubit/settings_game_cubit.dart b/lib/cubit/settings_game_cubit.dart
index b31cae3..677c18c 100644
--- a/lib/cubit/settings_game_cubit.dart
+++ b/lib/cubit/settings_game_cubit.dart
@@ -2,8 +2,8 @@ import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 
-import 'package:petitbac/models/settings_game.dart';
-import 'package:petitbac/utils/tools.dart';
+import 'package:petitbac/config/default_game_settings.dart';
+import 'package:petitbac/models/settings/settings_game.dart';
 
 part 'settings_game_state.dart';
 
@@ -11,8 +11,8 @@ class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
   GameSettingsCubit() : super(GameSettingsState(settings: GameSettings.createDefault()));
 
   void setValues({
-    int? itemsCount,
-    int? timerValue,
+    String? itemsCount,
+    String? timerValue,
   }) {
     emit(
       GameSettingsState(
@@ -24,22 +24,24 @@ class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
     );
   }
 
-  int getParameterValue(String code) {
+  String getParameterValue(String code) {
     switch (code) {
-      case 'itemsCount':
+      case DefaultGameSettings.parameterCodeItemsCount:
         return GameSettings.getItemsCountValueFromUnsafe(state.settings.itemsCount);
-      case 'timerValue':
+      case DefaultGameSettings.parameterCodeTimerValue:
         return GameSettings.getTimerValueFromUnsafe(state.settings.timerValue);
     }
-    return 0;
-  }
 
-  void setParameterValue(String code, int value) {
-    printlog('GameSettingsCubit.setParameterValue');
-    printlog('code: $code / value: $value');
+    return '';
+  }
 
-    int itemsCount = code == 'itemsCount' ? value : getParameterValue('itemsCount');
-    int timerValue = code == 'timerValue' ? value : getParameterValue('timerValue');
+  void setParameterValue(String code, String value) {
+    final String itemsCount = code == DefaultGameSettings.parameterCodeItemsCount
+        ? value
+        : getParameterValue(DefaultGameSettings.parameterCodeItemsCount);
+    final String timerValue = code == DefaultGameSettings.parameterCodeTimerValue
+        ? value
+        : getParameterValue(DefaultGameSettings.parameterCodeTimerValue);
 
     setValues(
       itemsCount: itemsCount,
@@ -49,8 +51,8 @@ class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
 
   @override
   GameSettingsState? fromJson(Map<String, dynamic> json) {
-    int itemsCount = json['itemsCount'] as int;
-    int timerValue = json['timerValue'] as int;
+    final String itemsCount = json[DefaultGameSettings.parameterCodeItemsCount] as String;
+    final String timerValue = json[DefaultGameSettings.parameterCodeTimerValue] as String;
 
     return GameSettingsState(
       settings: GameSettings(
@@ -63,8 +65,8 @@ class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
   @override
   Map<String, dynamic>? toJson(GameSettingsState state) {
     return <String, dynamic>{
-      'itemsCount': state.settings.itemsCount,
-      'timerValue': state.settings.timerValue,
+      DefaultGameSettings.parameterCodeItemsCount: state.settings.itemsCount,
+      DefaultGameSettings.parameterCodeTimerValue: state.settings.timerValue,
     };
   }
 }
diff --git a/lib/cubit/settings_game_state.dart b/lib/cubit/settings_game_state.dart
index b773dc6..5acd85b 100644
--- a/lib/cubit/settings_game_state.dart
+++ b/lib/cubit/settings_game_state.dart
@@ -12,8 +12,4 @@ class GameSettingsState extends Equatable {
   List<dynamic> get props => <dynamic>[
         settings,
       ];
-
-  Map<String, dynamic> get values => <String, dynamic>{
-        'settings': settings,
-      };
 }
diff --git a/lib/cubit/settings_global_cubit.dart b/lib/cubit/settings_global_cubit.dart
index 43f64fe..c4bfba2 100644
--- a/lib/cubit/settings_global_cubit.dart
+++ b/lib/cubit/settings_global_cubit.dart
@@ -2,43 +2,59 @@ import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 
-import 'package:petitbac/models/settings_global.dart';
-import 'package:petitbac/utils/tools.dart';
+import 'package:petitbac/config/default_global_settings.dart';
+import 'package:petitbac/models/settings/settings_global.dart';
 
 part 'settings_global_state.dart';
 
 class GlobalSettingsCubit extends HydratedCubit<GlobalSettingsState> {
   GlobalSettingsCubit() : super(GlobalSettingsState(settings: GlobalSettings.createDefault()));
 
-  void setValues() {
+  void setValues({
+    String? skin,
+  }) {
     emit(
       GlobalSettingsState(
-        settings: GlobalSettings(),
+        settings: GlobalSettings(
+          skin: skin ?? state.settings.skin,
+        ),
       ),
     );
   }
 
-  int getParameterValue(String code) {
-    switch (code) {}
-    return 0;
+  String getParameterValue(String code) {
+    switch (code) {
+      case DefaultGlobalSettings.parameterCodeSkin:
+        return GlobalSettings.getSkinValueFromUnsafe(state.settings.skin);
+    }
+    return '';
   }
 
-  void setParameterValue(String code, int value) {
-    printlog('GlobalSettingsCubit.setParameterValue');
-    printlog('code: $code / value: $value');
+  void setParameterValue(String code, String value) {
+    final String skin = (code == DefaultGlobalSettings.parameterCodeSkin)
+        ? value
+        : getParameterValue(DefaultGlobalSettings.parameterCodeSkin);
 
-    setValues();
+    setValues(
+      skin: skin,
+    );
   }
 
   @override
   GlobalSettingsState? fromJson(Map<String, dynamic> json) {
+    final String skin = json[DefaultGlobalSettings.parameterCodeSkin] as String;
+
     return GlobalSettingsState(
-      settings: GlobalSettings(),
+      settings: GlobalSettings(
+        skin: skin,
+      ),
     );
   }
 
   @override
   Map<String, dynamic>? toJson(GlobalSettingsState state) {
-    return <String, dynamic>{};
+    return <String, dynamic>{
+      DefaultGlobalSettings.parameterCodeSkin: state.settings.skin,
+    };
   }
 }
diff --git a/lib/cubit/settings_global_state.dart b/lib/cubit/settings_global_state.dart
index 4e4fbdf..ebcddd7 100644
--- a/lib/cubit/settings_global_state.dart
+++ b/lib/cubit/settings_global_state.dart
@@ -12,8 +12,4 @@ class GlobalSettingsState extends Equatable {
   List<dynamic> get props => <dynamic>[
         settings,
       ];
-
-  Map<String, dynamic> get values => <String, dynamic>{
-        'settings': settings,
-      };
 }
diff --git a/lib/data/fetch_data_helper.dart b/lib/data/fetch_data_helper.dart
index dc79648..f93d583 100644
--- a/lib/data/fetch_data_helper.dart
+++ b/lib/data/fetch_data_helper.dart
@@ -2,8 +2,8 @@ import 'dart:math';
 
 import 'package:petitbac/data/game_data.dart';
 import 'package:petitbac/models/data/category.dart';
-import 'package:petitbac/models/data/game_item.dart';
 import 'package:petitbac/models/data/letter.dart';
+import 'package:petitbac/models/game/game_item.dart';
 import 'package:petitbac/utils/tools.dart';
 
 class FetchDataHelper {
diff --git a/lib/main.dart b/lib/main.dart
index 4c088e7..0519f0f 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -2,6 +2,7 @@ import 'dart:io';
 
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:hive/hive.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
@@ -25,18 +26,17 @@ void main() async {
     storageDirectory: tmpDir,
   );
 
-  runApp(
-    EasyLocalization(
-      path: 'assets/translations',
-      supportedLocales: const <Locale>[
-        Locale('en'),
-        Locale('fr'),
-      ],
-      fallbackLocale: const Locale('en'),
-      useFallbackTranslations: true,
-      child: const MyApp(),
-    ),
-  );
+  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
+      .then((value) => runApp(EasyLocalization(
+            path: 'assets/translations',
+            supportedLocales: const <Locale>[
+              Locale('en'),
+              Locale('fr'),
+            ],
+            fallbackLocale: const Locale('en'),
+            useFallbackTranslations: true,
+            child: const MyApp(),
+          )));
 }
 
 class MyApp extends StatelessWidget {
@@ -44,6 +44,11 @@ class MyApp extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
+    final List<String> assets = getImagesAssets();
+    for (String asset in assets) {
+      precacheImage(AssetImage(asset), context);
+    }
+
     return MultiBlocProvider(
       providers: [
         BlocProvider<NavCubit>(create: (context) => NavCubit()),
@@ -73,4 +78,23 @@ class MyApp extends StatelessWidget {
       ),
     );
   }
+
+  List<String> getImagesAssets() {
+    final List<String> assets = [];
+
+    const List<String> gameImages = [
+      'button_back',
+      'button_delete_saved_game',
+      'button_resume_game',
+      'button_start',
+      'game_end',
+      'placeholder',
+    ];
+
+    for (String image in gameImages) {
+      assets.add('assets/ui/$image.png');
+    }
+
+    return assets;
+  }
 }
diff --git a/lib/models/game.dart b/lib/models/game.dart
deleted file mode 100644
index 9cdb175..0000000
--- a/lib/models/game.dart
+++ /dev/null
@@ -1,100 +0,0 @@
-import 'package:petitbac/data/fetch_data_helper.dart';
-import 'package:petitbac/models/data/category.dart';
-import 'package:petitbac/models/data/game_item.dart';
-import 'package:petitbac/models/data/letter.dart';
-import 'package:petitbac/models/settings_game.dart';
-import 'package:petitbac/models/settings_global.dart';
-import 'package:petitbac/utils/tools.dart';
-
-class Game {
-  final List<GameItem> items;
-  final GameSettings gameSettings;
-  final GlobalSettings globalSettings;
-  int countdown = 0;
-  int position = 0;
-  bool isRunning = false;
-  bool isFinished = false;
-
-  Game({
-    required this.items,
-    required this.gameSettings,
-    required this.globalSettings,
-    required this.countdown,
-    required this.position,
-    this.isRunning = false,
-    this.isFinished = false,
-  });
-
-  factory Game.createNull() {
-    return Game(
-      items: [],
-      gameSettings: GameSettings.createDefault(),
-      globalSettings: GlobalSettings.createDefault(),
-      countdown: 0,
-      position: 0,
-    );
-  }
-
-  factory Game.createNew({
-    GameSettings? gameSettings,
-    GlobalSettings? globalSettings,
-  }) {
-    GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
-    GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
-
-    List<GameItem> items = FetchDataHelper().getRandomItems(newGameSettings.itemsCount);
-
-    return Game(
-      items: items,
-      gameSettings: newGameSettings,
-      globalSettings: newGlobalSettings,
-      countdown: 0,
-      position: 0,
-      isRunning: true,
-      isFinished: false,
-    );
-  }
-
-  void stop() {
-    isRunning = false;
-  }
-
-  GameItem get item => items[position];
-  Category get category => item.category;
-  Letter get letter => item.letter;
-
-  void dump() {
-    printlog('');
-    printlog('## Current game dump:');
-    printlog('');
-    gameSettings.dump();
-    globalSettings.dump();
-    printlog('');
-    printlog('items:');
-    printlog(items.toString());
-    printlog('');
-    printlog('Game: ');
-    printlog('  isRunning: $isRunning');
-    printlog('  isFinished: $isFinished');
-    printlog('  position: $position');
-    printlog('  countdown: $countdown');
-    printlog('');
-  }
-
-  @override
-  String toString() {
-    return '$Game(${toJson()})';
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{
-      'items': items,
-      'gameSettings': gameSettings,
-      'globalSettings': globalSettings,
-      'countdown': countdown,
-      'position': position,
-      'isRunning': isRunning,
-      'isFinished': isFinished,
-    };
-  }
-}
diff --git a/lib/models/game/game.dart b/lib/models/game/game.dart
new file mode 100644
index 0000000..d9c4f87
--- /dev/null
+++ b/lib/models/game/game.dart
@@ -0,0 +1,125 @@
+import 'package:petitbac/data/fetch_data_helper.dart';
+import 'package:petitbac/models/data/category.dart';
+import 'package:petitbac/models/data/letter.dart';
+import 'package:petitbac/models/game/game_item.dart';
+import 'package:petitbac/models/settings/settings_game.dart';
+import 'package:petitbac/models/settings/settings_global.dart';
+import 'package:petitbac/utils/tools.dart';
+
+class Game {
+  Game({
+    // Settings
+    required this.gameSettings,
+    required this.globalSettings,
+
+    // State
+    this.isRunning = false,
+    this.isStarted = false,
+    this.isFinished = false,
+    this.animationInProgress = false,
+
+    // Base data
+    required this.items,
+
+    // Game data
+    this.position = 0,
+    this.countdown = 0,
+  });
+
+  // Settings
+  final GameSettings gameSettings;
+  final GlobalSettings globalSettings;
+
+  // State
+  bool isRunning;
+  bool isStarted;
+  bool isFinished;
+  bool animationInProgress;
+
+  // Base data
+  final List<GameItem> items;
+
+  // Game data
+  int position;
+  int countdown;
+
+  factory Game.createEmpty() {
+    return Game(
+      gameSettings: GameSettings.createDefault(),
+      globalSettings: GlobalSettings.createDefault(),
+      items: [],
+    );
+  }
+
+  factory Game.createNew({
+    GameSettings? gameSettings,
+    GlobalSettings? globalSettings,
+  }) {
+    final GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
+    final GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
+
+    final List<GameItem> items =
+        FetchDataHelper().getRandomItems(newGameSettings.itemsCountValue);
+
+    return Game(
+      // Settings
+      gameSettings: newGameSettings,
+      globalSettings: newGlobalSettings,
+      // State
+      isRunning: true,
+      isStarted: true,
+      // Base data
+      items: items,
+    );
+  }
+
+  bool get canBeResumed => isStarted && !isFinished;
+
+  GameItem get item => items[position];
+  Category get category => item.category;
+  Letter get letter => item.letter;
+
+  void dump() {
+    printlog('');
+    printlog('## Current game dump:');
+    printlog('');
+    printlog('$Game:');
+    printlog('  Settings');
+    gameSettings.dump();
+    globalSettings.dump();
+    printlog('  State');
+    printlog('    isRunning: $isRunning');
+    printlog('    isStarted: $isStarted');
+    printlog('    isFinished: $isFinished');
+    printlog('    animationInProgress: $animationInProgress');
+    printlog('  Base data');
+    printlog('    items: $items');
+    printlog('  Game data');
+    printlog('    position: $position');
+    printlog('    countdown: $countdown');
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$Game(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      // Settings
+      'gameSettings': gameSettings.toJson(),
+      'globalSettings': globalSettings.toJson(),
+      // State
+      'isRunning': isRunning,
+      'isStarted': isStarted,
+      'isFinished': isFinished,
+      'animationInProgress': animationInProgress,
+      // Base data
+      'items': items,
+      // Game data
+      'position': position,
+      'countdown': countdown,
+    };
+  }
+}
diff --git a/lib/models/data/game_item.dart b/lib/models/game/game_item.dart
similarity index 100%
rename from lib/models/data/game_item.dart
rename to lib/models/game/game_item.dart
diff --git a/lib/models/settings_game.dart b/lib/models/settings/settings_game.dart
similarity index 57%
rename from lib/models/settings_game.dart
rename to lib/models/settings/settings_game.dart
index 5262546..fe3d610 100644
--- a/lib/models/settings_game.dart
+++ b/lib/models/settings/settings_game.dart
@@ -2,15 +2,18 @@ import 'package:petitbac/config/default_game_settings.dart';
 import 'package:petitbac/utils/tools.dart';
 
 class GameSettings {
-  final int itemsCount;
-  final int timerValue;
+  final String itemsCount;
+  final String timerValue;
 
   GameSettings({
     required this.itemsCount,
     required this.timerValue,
   });
 
-  static int getItemsCountValueFromUnsafe(int itemsCount) {
+  int get itemsCountValue => DefaultGameSettings.getItemsCountValueFromCode(itemsCount);
+  int get timerCountValue => DefaultGameSettings.getTimerValueFromCode(timerValue);
+
+  static String getItemsCountValueFromUnsafe(String itemsCount) {
     if (DefaultGameSettings.allowedItemsCountValues.contains(itemsCount)) {
       return itemsCount;
     }
@@ -18,7 +21,7 @@ class GameSettings {
     return DefaultGameSettings.defaultItemsCountValue;
   }
 
-  static int getTimerValueFromUnsafe(int timerValue) {
+  static String getTimerValueFromUnsafe(String timerValue) {
     if (DefaultGameSettings.allowedTimerValues.contains(timerValue)) {
       return timerValue;
     }
@@ -34,9 +37,10 @@ class GameSettings {
   }
 
   void dump() {
-    printlog('Game settings: ');
-    printlog('  itemsCount: $itemsCount');
-    printlog('  timerValue: $timerValue');
+    printlog('$GameSettings:');
+    printlog('  ${DefaultGameSettings.parameterCodeItemsCount}: $itemsCount');
+    printlog('  ${DefaultGameSettings.parameterCodeTimerValue}: $timerValue');
+    printlog('');
   }
 
   @override
@@ -46,8 +50,8 @@ class GameSettings {
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
-      'itemsCount': itemsCount,
-      'timerValue': timerValue,
+      DefaultGameSettings.parameterCodeItemsCount: itemsCount,
+      DefaultGameSettings.parameterCodeTimerValue: timerValue,
     };
   }
 }
diff --git a/lib/models/settings/settings_global.dart b/lib/models/settings/settings_global.dart
new file mode 100644
index 0000000..6ac348a
--- /dev/null
+++ b/lib/models/settings/settings_global.dart
@@ -0,0 +1,41 @@
+import 'package:petitbac/config/default_global_settings.dart';
+import 'package:petitbac/utils/tools.dart';
+
+class GlobalSettings {
+  String skin;
+
+  GlobalSettings({
+    required this.skin,
+  });
+
+  static String getSkinValueFromUnsafe(String skin) {
+    if (DefaultGlobalSettings.allowedSkinValues.contains(skin)) {
+      return skin;
+    }
+
+    return DefaultGlobalSettings.defaultSkinValue;
+  }
+
+  factory GlobalSettings.createDefault() {
+    return GlobalSettings(
+      skin: DefaultGlobalSettings.defaultSkinValue,
+    );
+  }
+
+  void dump() {
+    printlog('$GlobalSettings:');
+    printlog('  ${DefaultGlobalSettings.parameterCodeSkin}: $skin');
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$GlobalSettings(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      DefaultGlobalSettings.parameterCodeSkin: skin,
+    };
+  }
+}
diff --git a/lib/models/settings_global.dart b/lib/models/settings_global.dart
deleted file mode 100644
index 2448620..0000000
--- a/lib/models/settings_global.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-import 'package:petitbac/utils/tools.dart';
-
-class GlobalSettings {
-  GlobalSettings();
-
-  factory GlobalSettings.createDefault() {
-    return GlobalSettings();
-  }
-
-  void dump() {
-    printlog('Global settings: ');
-    printlog('  (none)');
-  }
-
-  @override
-  String toString() {
-    return '$GlobalSettings(${toJson()})';
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{};
-  }
-}
diff --git a/lib/ui/game/game_end.dart b/lib/ui/game/game_end.dart
new file mode 100644
index 0000000..045c4d8
--- /dev/null
+++ b/lib/ui/game/game_end.dart
@@ -0,0 +1,57 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:petitbac/cubit/game_cubit.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/ui/widgets/actions/button_game_quit.dart';
+
+class GameEndWidget extends StatelessWidget {
+  const GameEndWidget({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        final Game currentGame = gameState.currentGame;
+
+        const Image decorationImage = Image(
+          image: AssetImage('assets/ui/game_end.png'),
+          fit: BoxFit.fill,
+        );
+
+        return Container(
+          margin: const EdgeInsets.all(2),
+          padding: const EdgeInsets.all(2),
+          child: Table(
+            defaultColumnWidth: const IntrinsicColumnWidth(),
+            children: [
+              TableRow(
+                children: [
+                  const Column(
+                    children: [decorationImage],
+                  ),
+                  const Column(
+                    children: [decorationImage],
+                  ),
+                  Column(
+                    children: [
+                      currentGame.animationInProgress == true
+                          ? decorationImage
+                          : const QuitGameButton()
+                    ],
+                  ),
+                  const Column(
+                    children: [decorationImage],
+                  ),
+                  const Column(
+                    children: [decorationImage],
+                  ),
+                ],
+              ),
+            ],
+          ),
+        );
+      },
+    );
+  }
+}
diff --git a/lib/ui/game/game_top.dart b/lib/ui/game/game_top.dart
new file mode 100644
index 0000000..2f7e2c7
--- /dev/null
+++ b/lib/ui/game/game_top.dart
@@ -0,0 +1,23 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:petitbac/cubit/game_cubit.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/ui/widgets/game/game_position_indicator.dart';
+
+class GameTopWidget extends StatelessWidget {
+  const GameTopWidget({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        final Game currentGame = gameState.currentGame;
+
+        return currentGame.gameSettings.itemsCountValue != 0
+            ? const GamePositionIndicator()
+            : const SizedBox.shrink();
+      },
+    );
+  }
+}
diff --git a/lib/ui/helpers/app_titles.dart b/lib/ui/helpers/app_titles.dart
new file mode 100644
index 0000000..b98107b
--- /dev/null
+++ b/lib/ui/helpers/app_titles.dart
@@ -0,0 +1,32 @@
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+
+class AppHeader extends StatelessWidget {
+  const AppHeader({super.key, required this.text});
+
+  final String text;
+
+  @override
+  Widget build(BuildContext context) {
+    return Text(
+      tr(text),
+      textAlign: TextAlign.start,
+      style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
+    );
+  }
+}
+
+class AppTitle extends StatelessWidget {
+  const AppTitle({super.key, required this.text});
+
+  final String text;
+
+  @override
+  Widget build(BuildContext context) {
+    return Text(
+      tr(text),
+      textAlign: TextAlign.start,
+      style: Theme.of(context).textTheme.titleLarge!.apply(fontWeightDelta: 2),
+    );
+  }
+}
diff --git a/lib/ui/widgets/helpers/outlined_text_widget.dart b/lib/ui/helpers/outlined_text_widget.dart
similarity index 100%
rename from lib/ui/widgets/helpers/outlined_text_widget.dart
rename to lib/ui/helpers/outlined_text_widget.dart
diff --git a/lib/ui/layouts/game_layout.dart b/lib/ui/layouts/game_layout.dart
new file mode 100644
index 0000000..27aaafc
--- /dev/null
+++ b/lib/ui/layouts/game_layout.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:petitbac/cubit/game_cubit.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/ui/game/game_end.dart';
+import 'package:petitbac/ui/game/game_top.dart';
+import 'package:petitbac/ui/widgets/game/game_board.dart';
+
+class GameLayout extends StatelessWidget {
+  const GameLayout({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        final Game currentGame = gameState.currentGame;
+
+        return Container(
+          alignment: AlignmentDirectional.topCenter,
+          padding: const EdgeInsets.all(4),
+          child: Column(
+            mainAxisAlignment: MainAxisAlignment.start,
+            crossAxisAlignment: CrossAxisAlignment.center,
+            children: [
+              const GameTopWidget(),
+              const SizedBox(height: 8),
+              const GameBoardWidget(),
+              const SizedBox(height: 8),
+              const Expanded(child: SizedBox.shrink()),
+              currentGame.isFinished ? const GameEndWidget() : const SizedBox.shrink(),
+            ],
+          ),
+        );
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/parameters.dart b/lib/ui/layouts/parameters_layout.dart
similarity index 52%
rename from lib/ui/widgets/parameters.dart
rename to lib/ui/layouts/parameters_layout.dart
index c13ccba..0751974 100644
--- a/lib/ui/widgets/parameters.dart
+++ b/lib/ui/layouts/parameters_layout.dart
@@ -5,11 +5,16 @@ import 'package:petitbac/config/default_game_settings.dart';
 import 'package:petitbac/config/default_global_settings.dart';
 import 'package:petitbac/cubit/settings_game_cubit.dart';
 import 'package:petitbac/cubit/settings_global_cubit.dart';
-import 'package:petitbac/ui/painters/parameter_painter.dart';
-import 'package:petitbac/ui/widgets/button_game_start_new.dart';
+import 'package:petitbac/ui/parameters/parameter_image.dart';
+import 'package:petitbac/ui/parameters/parameter_painter.dart';
+import 'package:petitbac/ui/widgets/actions/button_delete_saved_game.dart';
+import 'package:petitbac/ui/widgets/actions/button_game_start_new.dart';
+import 'package:petitbac/ui/widgets/actions/button_resume_saved_game.dart';
 
-class Parameters extends StatelessWidget {
-  const Parameters({super.key});
+class ParametersLayout extends StatelessWidget {
+  const ParametersLayout({super.key, required this.canResume});
+
+  final bool canResume;
 
   final double separatorHeight = 8.0;
 
@@ -31,7 +36,24 @@ class Parameters extends StatelessWidget {
     }
 
     lines.add(SizedBox(height: separatorHeight));
-    lines.add(const Expanded(child: StartNewGameButton()));
+
+    if (canResume == false) {
+      // Start new game
+      lines.add(const Expanded(
+        child: StartNewGameButton(),
+      ));
+    } else {
+      // Resume game
+      lines.add(const Expanded(
+        child: ResumeSavedGameButton(),
+      ));
+      // Delete saved game
+      lines.add(SizedBox.square(
+        dimension: MediaQuery.of(context).size.width / 4,
+        child: const DeleteSavedGameButton(),
+      ));
+    }
+
     lines.add(SizedBox(height: separatorHeight));
 
     // Global settings
@@ -58,7 +80,7 @@ class Parameters extends StatelessWidget {
   }) {
     final List<Widget> parameterButtons = [];
 
-    final List<int> availableValues = isGlobal
+    final List<String> availableValues = isGlobal
         ? DefaultGlobalSettings.getAvailableValues(code)
         : DefaultGameSettings.getAvailableValues(code);
 
@@ -66,7 +88,7 @@ class Parameters extends StatelessWidget {
       return [];
     }
 
-    for (int value in availableValues) {
+    for (String value in availableValues) {
       final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
         builder: (BuildContext context, GameSettingsState gameSettingsState) {
           return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
@@ -76,7 +98,7 @@ class Parameters extends StatelessWidget {
               final GlobalSettingsCubit globalSettingsCubit =
                   BlocProvider.of<GlobalSettingsCubit>(context);
 
-              final int currentValue = isGlobal
+              final String currentValue = isGlobal
                   ? globalSettingsCubit.getParameterValue(code)
                   : gameSettingsCubit.getParameterValue(code);
 
@@ -85,22 +107,39 @@ class Parameters extends StatelessWidget {
               final double displayWidth = MediaQuery.of(context).size.width;
               final double itemWidth = displayWidth / availableValues.length - 26;
 
+              final bool displayedWithAssets =
+                  DefaultGlobalSettings.displayedWithAssets.contains(code) ||
+                      DefaultGameSettings.displayedWithAssets.contains(code);
+
               return TextButton(
-                child: CustomPaint(
-                  size: Size(itemWidth, itemWidth),
-                  willChange: false,
-                  painter: ParameterPainter(
-                    code: code,
-                    value: value,
-                    isSelected: isActive,
-                    gameSettings: gameSettingsState.settings,
-                    globalSettings: globalSettingsState.settings,
-                  ),
-                  isComplex: true,
+                child: Container(
+                  child: displayedWithAssets
+                      ? SizedBox.square(
+                          dimension: itemWidth,
+                          child: ParameterImage(
+                            code: code,
+                            value: value,
+                            isSelected: isActive,
+                          ),
+                        )
+                      : CustomPaint(
+                          size: Size(itemWidth, itemWidth),
+                          willChange: false,
+                          painter: ParameterPainter(
+                            code: code,
+                            value: value,
+                            isSelected: isActive,
+                            gameSettings: gameSettingsState.settings,
+                            globalSettings: globalSettingsState.settings,
+                          ),
+                          isComplex: true,
+                        ),
                 ),
-                onPressed: () => isGlobal
-                    ? globalSettingsCubit.setParameterValue(code, value)
-                    : gameSettingsCubit.setParameterValue(code, value),
+                onPressed: () {
+                  isGlobal
+                      ? globalSettingsCubit.setParameterValue(code, value)
+                      : gameSettingsCubit.setParameterValue(code, value);
+                },
               );
             },
           );
diff --git a/lib/ui/parameters/parameter_image.dart b/lib/ui/parameters/parameter_image.dart
new file mode 100644
index 0000000..fc4b576
--- /dev/null
+++ b/lib/ui/parameters/parameter_image.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+
+class ParameterImage extends StatelessWidget {
+  const ParameterImage({
+    super.key,
+    required this.code,
+    required this.value,
+    required this.isSelected,
+  });
+
+  final String code;
+  final String value;
+  final bool isSelected;
+
+  static const Color buttonBackgroundColor = Colors.white;
+  static const Color buttonBorderColorActive = Colors.blue;
+  static const Color buttonBorderColorInactive = Colors.white;
+  static const double buttonBorderWidth = 8.0;
+  static const double buttonBorderRadius = 8.0;
+
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      decoration: BoxDecoration(
+        color: buttonBackgroundColor,
+        borderRadius: BorderRadius.circular(buttonBorderRadius),
+        border: Border.all(
+          color: isSelected ? buttonBorderColorActive : buttonBorderColorInactive,
+          width: buttonBorderWidth,
+        ),
+      ),
+      child: Image(
+        image: AssetImage('assets/ui/${code}_$value.png'),
+        fit: BoxFit.fill,
+      ),
+    );
+  }
+}
diff --git a/lib/ui/painters/parameter_painter.dart b/lib/ui/parameters/parameter_painter.dart
similarity index 87%
rename from lib/ui/painters/parameter_painter.dart
rename to lib/ui/parameters/parameter_painter.dart
index 2509c75..49e5190 100644
--- a/lib/ui/painters/parameter_painter.dart
+++ b/lib/ui/parameters/parameter_painter.dart
@@ -3,8 +3,8 @@ import 'dart:math';
 import 'package:flutter/material.dart';
 
 import 'package:petitbac/config/default_game_settings.dart';
-import 'package:petitbac/models/settings_game.dart';
-import 'package:petitbac/models/settings_global.dart';
+import 'package:petitbac/models/settings/settings_game.dart';
+import 'package:petitbac/models/settings/settings_global.dart';
 import 'package:petitbac/utils/tools.dart';
 
 class ParameterPainter extends CustomPainter {
@@ -17,7 +17,7 @@ class ParameterPainter extends CustomPainter {
   });
 
   final String code;
-  final int value;
+  final String value;
   final bool isSelected;
   final GameSettings gameSettings;
   final GlobalSettings globalSettings;
@@ -60,7 +60,7 @@ class ParameterPainter extends CustomPainter {
 
   // "unknown" parameter -> simple block with text
   void paintUnknownParameterItem(
-    final int value,
+    final String value,
     final Canvas canvas,
     final double size,
   ) {
@@ -96,14 +96,14 @@ class ParameterPainter extends CustomPainter {
   }
 
   void paintItemsCountParameterItem(
-    final int value,
+    final String value,
     final Canvas canvas,
     final double size,
   ) {
-    const itemCountEmoji = '💬\n';
+    const itemCountEmoji = '💬';
 
     Color backgroundColor = Colors.grey;
-    String text = '';
+    String text = '$itemCountEmoji\n${DefaultGameSettings.getItemsCountValueFromCode(value)}';
 
     switch (value) {
       case DefaultGameSettings.itemsCountValueNoLimit:
@@ -112,15 +112,12 @@ class ParameterPainter extends CustomPainter {
         break;
       case DefaultGameSettings.itemsCountValueShort:
         backgroundColor = Colors.green;
-        text = itemCountEmoji + DefaultGameSettings.itemsCountValueShort.toString();
         break;
       case DefaultGameSettings.itemsCountValueMedium:
         backgroundColor = Colors.orange;
-        text = itemCountEmoji + DefaultGameSettings.itemsCountValueMedium.toString();
         break;
       case DefaultGameSettings.itemsCountValueLong:
         backgroundColor = Colors.red;
-        text = itemCountEmoji + DefaultGameSettings.itemsCountValueLong.toString();
         break;
       default:
         printlog('Wrong value for itemsCount parameter value: $value');
@@ -160,14 +157,14 @@ class ParameterPainter extends CustomPainter {
   }
 
   void paintTimerParameterItem(
-    final int value,
+    final String value,
     final Canvas canvas,
     final double size,
   ) {
-    const timerEmoji = '⏲️\n';
+    const timerEmoji = '⏲️';
 
     Color backgroundColor = Colors.grey;
-    String text = '';
+    String text = '$timerEmoji\n${DefaultGameSettings.getTimerValueFromCode(value)}"';
 
     switch (value) {
       case DefaultGameSettings.timerValueNoTimer:
@@ -176,15 +173,12 @@ class ParameterPainter extends CustomPainter {
         break;
       case DefaultGameSettings.timerValueLow:
         backgroundColor = Colors.green;
-        text = '$timerEmoji${DefaultGameSettings.timerValueLow}"';
         break;
       case DefaultGameSettings.timerValueMedium:
         backgroundColor = Colors.orange;
-        text = '$timerEmoji${DefaultGameSettings.timerValueMedium}"';
         break;
       case DefaultGameSettings.timerValueHigh:
         backgroundColor = Colors.red;
-        text = '$timerEmoji${DefaultGameSettings.timerValueHigh}"';
         break;
       default:
         printlog('Wrong value for itemsCount parameter value: $value');
@@ -192,7 +186,7 @@ class ParameterPainter extends CustomPainter {
 
     final paint = Paint();
     paint.strokeJoin = StrokeJoin.round;
-    paint.strokeWidth = 3 / 100 * size;
+    paint.strokeWidth = 3;
 
     // Colored background
     paint.color = backgroundColor;
diff --git a/lib/ui/screens/page_about.dart b/lib/ui/screens/page_about.dart
index 1720556..8f2a3d6 100644
--- a/lib/ui/screens/page_about.dart
+++ b/lib/ui/screens/page_about.dart
@@ -2,36 +2,40 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 
-import 'package:petitbac/ui/widgets/helpers/app_header.dart';
+import 'package:petitbac/ui/helpers/app_titles.dart';
 
 class PageAbout extends StatelessWidget {
   const PageAbout({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return Column(
-      mainAxisAlignment: MainAxisAlignment.start,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      mainAxisSize: MainAxisSize.max,
-      children: <Widget>[
-        const AppHeader(text: 'about_title'),
-        const Text('about_content').tr(),
-        FutureBuilder<PackageInfo>(
-          future: PackageInfo.fromPlatform(),
-          builder: (context, snapshot) {
-            switch (snapshot.connectionState) {
-              case ConnectionState.done:
-                return const Text('about_version').tr(
-                  namedArgs: {
-                    'version': snapshot.data!.version,
-                  },
-                );
-              default:
-                return const SizedBox();
-            }
-          },
-        ),
-      ],
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 8),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisSize: MainAxisSize.max,
+        children: <Widget>[
+          const SizedBox(height: 8),
+          const AppTitle(text: 'about_title'),
+          const Text('about_content').tr(),
+          FutureBuilder<PackageInfo>(
+            future: PackageInfo.fromPlatform(),
+            builder: (context, snapshot) {
+              switch (snapshot.connectionState) {
+                case ConnectionState.done:
+                  return const Text('about_version').tr(
+                    namedArgs: {
+                      'version': snapshot.data!.version,
+                    },
+                  );
+                default:
+                  return const SizedBox();
+              }
+            },
+          ),
+        ],
+      ),
     );
   }
 }
diff --git a/lib/ui/screens/page_game.dart b/lib/ui/screens/page_game.dart
index 933478a..fd6bfec 100644
--- a/lib/ui/screens/page_game.dart
+++ b/lib/ui/screens/page_game.dart
@@ -2,8 +2,9 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:petitbac/cubit/game_cubit.dart';
-import 'package:petitbac/ui/widgets/game/game.dart';
-import 'package:petitbac/ui/widgets/parameters.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/ui/layouts/game_layout.dart';
+import 'package:petitbac/ui/layouts/parameters_layout.dart';
 
 class PageGame extends StatelessWidget {
   const PageGame({super.key});
@@ -11,8 +12,13 @@ class PageGame extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return BlocBuilder<GameCubit, GameState>(
-        builder: (BuildContext context, GameState gameState) {
-      return gameState.currentGame.isRunning ? const GameWidget() : const Parameters();
-    });
+      builder: (BuildContext context, GameState gameState) {
+        final Game currentGame = gameState.currentGame;
+
+        return currentGame.isRunning
+            ? const GameLayout()
+            : ParametersLayout(canResume: currentGame.canBeResumed);
+      },
+    );
   }
 }
diff --git a/lib/ui/screens/page_settings.dart b/lib/ui/screens/page_settings.dart
index d8690b9..433f4dc 100644
--- a/lib/ui/screens/page_settings.dart
+++ b/lib/ui/screens/page_settings.dart
@@ -1,22 +1,26 @@
 import 'package:flutter/material.dart';
 
-import 'package:petitbac/ui/widgets/helpers/app_header.dart';
-import 'package:petitbac/ui/widgets/settings/settings_form.dart';
+import 'package:petitbac/ui/helpers/app_titles.dart';
+import 'package:petitbac/ui/settings/settings_form.dart';
 
 class PageSettings extends StatelessWidget {
   const PageSettings({super.key});
 
   @override
   Widget build(BuildContext context) {
-    return const Column(
-      mainAxisAlignment: MainAxisAlignment.start,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      mainAxisSize: MainAxisSize.max,
-      children: <Widget>[
-        AppHeader(text: 'settings_title'),
-        SizedBox(height: 8),
-        SettingsForm(),
-      ],
+    return const Padding(
+      padding: EdgeInsets.symmetric(horizontal: 8),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisSize: MainAxisSize.max,
+        children: <Widget>[
+          SizedBox(height: 8),
+          AppTitle(text: 'settings_title'),
+          SizedBox(height: 8),
+          SettingsForm(),
+        ],
+      ),
     );
   }
 }
diff --git a/lib/ui/widgets/settings/settings_form.dart b/lib/ui/settings/settings_form.dart
similarity index 96%
rename from lib/ui/widgets/settings/settings_form.dart
rename to lib/ui/settings/settings_form.dart
index eef343a..f51c716 100644
--- a/lib/ui/widgets/settings/settings_form.dart
+++ b/lib/ui/settings/settings_form.dart
@@ -2,7 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:unicons/unicons.dart';
 
-import 'package:petitbac/ui/widgets/settings/theme_card.dart';
+import 'package:petitbac/ui/settings/theme_card.dart';
 
 class SettingsForm extends StatefulWidget {
   const SettingsForm({super.key});
diff --git a/lib/ui/widgets/settings/theme_card.dart b/lib/ui/settings/theme_card.dart
similarity index 100%
rename from lib/ui/widgets/settings/theme_card.dart
rename to lib/ui/settings/theme_card.dart
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index 789d18b..bd4614b 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -14,7 +14,7 @@ class SkeletonScreen extends StatelessWidget {
       appBar: const GlobalAppBar(),
       extendBodyBehindAppBar: false,
       body: Material(
-        color: Theme.of(context).colorScheme.background,
+        color: Theme.of(context).colorScheme.surface,
         child: BlocBuilder<NavCubit, int>(
           builder: (BuildContext context, int pageIndex) {
             return Padding(
@@ -28,7 +28,7 @@ class SkeletonScreen extends StatelessWidget {
           },
         ),
       ),
-      backgroundColor: Theme.of(context).colorScheme.background,
+      backgroundColor: Theme.of(context).colorScheme.surface,
     );
   }
 }
diff --git a/lib/ui/widgets/actions/button_delete_saved_game.dart b/lib/ui/widgets/actions/button_delete_saved_game.dart
new file mode 100644
index 0000000..611b237
--- /dev/null
+++ b/lib/ui/widgets/actions/button_delete_saved_game.dart
@@ -0,0 +1,21 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:petitbac/cubit/game_cubit.dart';
+
+class DeleteSavedGameButton extends StatelessWidget {
+  const DeleteSavedGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return TextButton(
+      child: const Image(
+        image: AssetImage('assets/ui/button_delete_saved_game.png'),
+        fit: BoxFit.fill,
+      ),
+      onPressed: () {
+        BlocProvider.of<GameCubit>(context).deleteSavedGame();
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/actions/button_game_quit.dart b/lib/ui/widgets/actions/button_game_quit.dart
new file mode 100644
index 0000000..b4691ad
--- /dev/null
+++ b/lib/ui/widgets/actions/button_game_quit.dart
@@ -0,0 +1,21 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:petitbac/cubit/game_cubit.dart';
+
+class QuitGameButton extends StatelessWidget {
+  const QuitGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return TextButton(
+      child: const Image(
+        image: AssetImage('assets/ui/button_back.png'),
+        fit: BoxFit.fill,
+      ),
+      onPressed: () {
+        BlocProvider.of<GameCubit>(context).quitGame();
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/button_game_start_new.dart b/lib/ui/widgets/actions/button_game_start_new.dart
similarity index 72%
rename from lib/ui/widgets/button_game_start_new.dart
rename to lib/ui/widgets/actions/button_game_start_new.dart
index 2b0ca95..067a2d3 100644
--- a/lib/ui/widgets/button_game_start_new.dart
+++ b/lib/ui/widgets/actions/button_game_start_new.dart
@@ -14,17 +14,17 @@ class StartNewGameButton extends StatelessWidget {
       builder: (BuildContext context, GameSettingsState gameSettingsState) {
         return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
           builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
-            final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-
             return TextButton(
               child: const Image(
-                image: AssetImage('assets/icons/button_start.png'),
+                image: AssetImage('assets/ui/button_start.png'),
                 fit: BoxFit.fill,
               ),
-              onPressed: () => gameCubit.startNewGame(
-                gameSettings: gameSettingsState.settings,
-                globalSettings: globalSettingsState.settings,
-              ),
+              onPressed: () {
+                BlocProvider.of<GameCubit>(context).startNewGame(
+                  gameSettings: gameSettingsState.settings,
+                  globalSettings: globalSettingsState.settings,
+                );
+              },
             );
           },
         );
diff --git a/lib/ui/widgets/actions/button_resume_saved_game.dart b/lib/ui/widgets/actions/button_resume_saved_game.dart
new file mode 100644
index 0000000..6119772
--- /dev/null
+++ b/lib/ui/widgets/actions/button_resume_saved_game.dart
@@ -0,0 +1,21 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:petitbac/cubit/game_cubit.dart';
+
+class ResumeSavedGameButton extends StatelessWidget {
+  const ResumeSavedGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return TextButton(
+      child: const Image(
+        image: AssetImage('assets/ui/button_resume_game.png'),
+        fit: BoxFit.fill,
+      ),
+      onPressed: () {
+        BlocProvider.of<GameCubit>(context).resumeSavedGame();
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/game/game.dart b/lib/ui/widgets/game/game.dart
deleted file mode 100644
index b7384eb..0000000
--- a/lib/ui/widgets/game/game.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'package:petitbac/cubit/game_cubit.dart';
-import 'package:petitbac/models/game.dart';
-import 'package:petitbac/ui/widgets/game/game_countdown.dart';
-import 'package:petitbac/ui/widgets/game/game_position_indicator.dart';
-import 'package:petitbac/ui/widgets/game/widget_category.dart';
-import 'package:petitbac/ui/widgets/game/widget_letter.dart';
-
-class GameWidget extends StatelessWidget {
-  const GameWidget({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
-
-        return Center(
-          child: Column(
-            mainAxisAlignment: MainAxisAlignment.start,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              currentGame.gameSettings.itemsCount != 0
-                  ? const GamePositionIndicator()
-                  : const SizedBox.shrink(),
-              const WidgetLetter(),
-              const GameButtonNextWithCountdown(),
-              const WidgetCategory(),
-            ],
-          ),
-        );
-      },
-    );
-  }
-}
diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart
new file mode 100644
index 0000000..a3bc232
--- /dev/null
+++ b/lib/ui/widgets/game/game_board.dart
@@ -0,0 +1,22 @@
+import 'package:flutter/material.dart';
+
+import 'package:petitbac/ui/widgets/game/game_countdown.dart';
+import 'package:petitbac/ui/widgets/game/widget_category.dart';
+import 'package:petitbac/ui/widgets/game/widget_letter.dart';
+
+class GameBoardWidget extends StatelessWidget {
+  const GameBoardWidget({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const Column(
+      mainAxisAlignment: MainAxisAlignment.start,
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        WidgetLetter(),
+        GameButtonNextWithCountdown(),
+        WidgetCategory(),
+      ],
+    );
+  }
+}
diff --git a/lib/ui/widgets/game/game_countdown.dart b/lib/ui/widgets/game/game_countdown.dart
index fdbd0f4..8e4510a 100644
--- a/lib/ui/widgets/game/game_countdown.dart
+++ b/lib/ui/widgets/game/game_countdown.dart
@@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:petitbac/cubit/game_cubit.dart';
 import 'package:petitbac/cubit/settings_game_cubit.dart';
-import 'package:petitbac/models/game.dart';
+import 'package:petitbac/models/game/game.dart';
 import 'package:petitbac/utils/color_extensions.dart';
 
 class GameButtonNextWithCountdown extends StatelessWidget {
@@ -48,7 +48,7 @@ class GameButtonNextWithCountdown extends StatelessWidget {
                         if (currentGame.isFinished) {
                           gameCubit.quitGame();
                         } else {
-                          if (currentGame.gameSettings.itemsCount == 0) {
+                          if (currentGame.gameSettings.itemsCountValue == 0) {
                             gameCubit.pickNewItem();
                             gameCubit.startTimer();
                           } else {
diff --git a/lib/ui/widgets/game/game_position_indicator.dart b/lib/ui/widgets/game/game_position_indicator.dart
index 2d850ba..5298b45 100644
--- a/lib/ui/widgets/game/game_position_indicator.dart
+++ b/lib/ui/widgets/game/game_position_indicator.dart
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:petitbac/cubit/game_cubit.dart';
-import 'package:petitbac/models/game.dart';
-import 'package:petitbac/ui/widgets/helpers/outlined_text_widget.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/ui/helpers/outlined_text_widget.dart';
 import 'package:petitbac/utils/color_extensions.dart';
 
 class GamePositionIndicator extends StatelessWidget {
@@ -16,7 +16,7 @@ class GamePositionIndicator extends StatelessWidget {
         final Game currentGame = gameState.currentGame;
 
         final int currentPosition = currentGame.position + 1;
-        final int maxPosition = currentGame.gameSettings.itemsCount;
+        final int maxPosition = currentGame.gameSettings.itemsCountValue;
 
         // Normalized [0..1] value
         final double barValue = currentPosition / maxPosition;
diff --git a/lib/ui/widgets/game/widget_category.dart b/lib/ui/widgets/game/widget_category.dart
index 61d41ea..c86fd3d 100644
--- a/lib/ui/widgets/game/widget_category.dart
+++ b/lib/ui/widgets/game/widget_category.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:petitbac/cubit/game_cubit.dart';
-import 'package:petitbac/models/game.dart';
+import 'package:petitbac/models/game/game.dart';
 import 'package:petitbac/utils/color_extensions.dart';
 
 class WidgetCategory extends StatelessWidget {
@@ -35,8 +35,7 @@ class WidgetCategory extends StatelessWidget {
             height: 180,
             child: TextButton(
               onPressed: () {
-                final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-                gameCubit.pickNewCategory();
+                BlocProvider.of<GameCubit>(context).pickNewCategory();
               },
               child: Column(
                 mainAxisAlignment: MainAxisAlignment.center,
diff --git a/lib/ui/widgets/game/widget_letter.dart b/lib/ui/widgets/game/widget_letter.dart
index dbdea5f..df1db43 100644
--- a/lib/ui/widgets/game/widget_letter.dart
+++ b/lib/ui/widgets/game/widget_letter.dart
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:petitbac/cubit/game_cubit.dart';
-import 'package:petitbac/models/game.dart';
-import 'package:petitbac/ui/widgets/helpers/outlined_text_widget.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/ui/helpers/outlined_text_widget.dart';
 import 'package:petitbac/utils/color_extensions.dart';
 
 class WidgetLetter extends StatelessWidget {
@@ -36,8 +36,7 @@ class WidgetLetter extends StatelessWidget {
             height: 100,
             child: TextButton(
               onPressed: () {
-                final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-                gameCubit.pickNewLetter();
+                BlocProvider.of<GameCubit>(context).pickNewLetter();
               },
               child: OutlinedText(
                 text: currentGame.letter.text,
diff --git a/lib/ui/widgets/global_app_bar.dart b/lib/ui/widgets/global_app_bar.dart
index 512717a..e64acbd 100644
--- a/lib/ui/widgets/global_app_bar.dart
+++ b/lib/ui/widgets/global_app_bar.dart
@@ -4,8 +4,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:petitbac/config/menu.dart';
 import 'package:petitbac/cubit/game_cubit.dart';
 import 'package:petitbac/cubit/nav_cubit.dart';
-import 'package:petitbac/models/game.dart';
-import 'package:petitbac/ui/widgets/helpers/app_title.dart';
+import 'package:petitbac/models/game/game.dart';
+import 'package:petitbac/ui/helpers/app_titles.dart';
 
 class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
   const GlobalAppBar({super.key});
@@ -20,16 +20,15 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
 
             final List<Widget> menuActions = [];
 
-            if (currentGame.isRunning) {
+            if (currentGame.isRunning && !currentGame.isFinished) {
               menuActions.add(TextButton(
                 child: const Image(
-                  image: AssetImage('assets/icons/button_back.png'),
+                  image: AssetImage('assets/ui/button_back.png'),
                   fit: BoxFit.fill,
                 ),
                 onPressed: () {},
                 onLongPress: () {
-                  final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-                  gameCubit.quitGame();
+                  BlocProvider.of<GameCubit>(context).quitGame();
                 },
               ));
             } else {
@@ -70,7 +69,7 @@ class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
             }
 
             return AppBar(
-              title: const AppTitle(text: 'app_name'),
+              title: const AppHeader(text: 'app_name'),
               actions: menuActions,
             );
           },
diff --git a/lib/ui/widgets/helpers/app_header.dart b/lib/ui/widgets/helpers/app_header.dart
deleted file mode 100644
index b5c5be0..0000000
--- a/lib/ui/widgets/helpers/app_header.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-
-class AppHeader extends StatelessWidget {
-  const AppHeader({super.key, required this.text});
-
-  final String text;
-
-  @override
-  Widget build(BuildContext context) {
-    return Column(
-      mainAxisAlignment: MainAxisAlignment.start,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      children: [
-        Text(
-          tr(text),
-          textAlign: TextAlign.start,
-          style: Theme.of(context).textTheme.headlineSmall!.apply(fontWeightDelta: 2),
-        ),
-        const SizedBox(height: 8),
-      ],
-    );
-  }
-}
diff --git a/lib/ui/widgets/helpers/app_title.dart b/lib/ui/widgets/helpers/app_title.dart
deleted file mode 100644
index 7cbbb20..0000000
--- a/lib/ui/widgets/helpers/app_title.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-
-class AppTitle extends StatelessWidget {
-  const AppTitle({super.key, required this.text});
-
-  final String text;
-
-  @override
-  Widget build(BuildContext context) {
-    return Text(
-      tr(text),
-      textAlign: TextAlign.start,
-      style: Theme.of(context).textTheme.headlineLarge!.apply(fontWeightDelta: 2),
-    );
-  }
-}
diff --git a/pubspec.lock b/pubspec.lock
index bdba0ef..e0ab96e 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -106,10 +106,10 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_bloc
-      sha256: f0ecf6e6eb955193ca60af2d5ca39565a86b8a142452c5b24d96fb477428f4d2
+      sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
       url: "https://pub.dev"
     source: hosted
-    version: "8.1.5"
+    version: "8.1.6"
   flutter_lints:
     dependency: "direct dev"
     description:
@@ -164,10 +164,10 @@ packages:
     dependency: transitive
     description:
       name: intl
-      sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
+      sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
       url: "https://pub.dev"
     source: hosted
-    version: "0.18.1"
+    version: "0.19.0"
   lints:
     dependency: transitive
     description:
@@ -188,10 +188,10 @@ packages:
     dependency: transitive
     description:
       name: meta
-      sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+      sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
       url: "https://pub.dev"
     source: hosted
-    version: "1.11.0"
+    version: "1.12.0"
   nested:
     dependency: transitive
     description:
@@ -236,10 +236,10 @@ packages:
     dependency: transitive
     description:
       name: path_provider_android
-      sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
+      sha256: "9c96da072b421e98183f9ea7464898428e764bc0ce5567f27ec8693442e72514"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.4"
+    version: "2.2.5"
   path_provider_foundation:
     dependency: transitive
     description:
@@ -276,10 +276,10 @@ packages:
     dependency: transitive
     description:
       name: platform
-      sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
+      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.4"
+    version: "3.1.5"
   plugin_platform_interface:
     dependency: transitive
     description:
@@ -308,10 +308,10 @@ packages:
     dependency: transitive
     description:
       name: shared_preferences_android
-      sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
+      sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.2"
+    version: "2.2.3"
   shared_preferences_foundation:
     dependency: transitive
     description:
@@ -425,10 +425,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
+      sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
       url: "https://pub.dev"
     source: hosted
-    version: "5.5.0"
+    version: "5.5.1"
   xdg_directories:
     dependency: transitive
     description:
@@ -438,5 +438,5 @@ packages:
     source: hosted
     version: "1.0.4"
 sdks:
-  dart: ">=3.3.0 <4.0.0"
-  flutter: ">=3.19.0"
+  dart: ">=3.4.0 <4.0.0"
+  flutter: ">=3.22.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 7a18da7..00f81f9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: A PetitBac game application.
 
 publish_to: "none"
 
-version: 1.2.33+39
+version: 1.3.0+40
 
 environment:
   sdk: "^3.0.0"
@@ -12,6 +12,7 @@ dependencies:
   flutter:
     sdk: flutter
 
+  # base
   easy_localization: ^3.0.1
   equatable: ^2.0.5
   flutter_bloc: ^8.1.1
@@ -21,13 +22,16 @@ dependencies:
   path_provider: ^2.0.11
   unicons: ^2.1.1
 
+  # specific
+  # (none)
+
 dev_dependencies:
   flutter_lints: ^4.0.0
 
 flutter:
   uses-material-design: true
   assets:
-    - assets/icons/
+    - assets/ui/
     - assets/translations/
 
   fonts:
@@ -41,3 +45,4 @@ flutter:
           weight: 400
         - asset: assets/fonts/Nunito-Light.ttf
           weight: 300
+
diff --git a/icons/build_application_icons.sh b/resources/app/build_application_resources.sh
similarity index 98%
rename from icons/build_application_icons.sh
rename to resources/app/build_application_resources.sh
index 27dbe26..6d67b8f 100755
--- a/icons/build_application_icons.sh
+++ b/resources/app/build_application_resources.sh
@@ -6,7 +6,7 @@ command -v scour >/dev/null 2>&1 || { echo >&2 "I require scour but it's not ins
 command -v optipng >/dev/null 2>&1 || { echo >&2 "I require optipng but it's not installed. Aborting."; exit 1; }
 
 CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
-BASE_DIR="$(dirname "${CURRENT_DIR}")"
+BASE_DIR="$(dirname "$(dirname "${CURRENT_DIR}")")"
 
 SOURCE_ICON="${CURRENT_DIR}/icon.svg"
 SOURCE_FASTLANE="${CURRENT_DIR}/featureGraphic.svg"
diff --git a/icons/featureGraphic.svg b/resources/app/featureGraphic.svg
similarity index 100%
rename from icons/featureGraphic.svg
rename to resources/app/featureGraphic.svg
diff --git a/icons/icon.svg b/resources/app/icon.svg
similarity index 100%
rename from icons/icon.svg
rename to resources/app/icon.svg
diff --git a/resources/build_resources.sh b/resources/build_resources.sh
new file mode 100755
index 0000000..6b80eb9
--- /dev/null
+++ b/resources/build_resources.sh
@@ -0,0 +1,8 @@
+#! /bin/bash
+
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
+
+${CURRENT_DIR}/app/build_application_resources.sh
+${CURRENT_DIR}/ui/build_ui_resources.sh
+
+${CURRENT_DIR}/data/build_categories_list.sh
diff --git a/scripts/build_categories_list.sh b/resources/data/build_categories_list.sh
similarity index 98%
rename from scripts/build_categories_list.sh
rename to resources/data/build_categories_list.sh
index 8453c9e..ff4459a 100755
--- a/scripts/build_categories_list.sh
+++ b/resources/data/build_categories_list.sh
@@ -3,7 +3,7 @@
 command -v jq >/dev/null 2>&1 || { echo >&2 "I require jq (json parser) but it's not installed. Aborting."; exit 1; }
 
 CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
-BASE_DIR="$(dirname "${CURRENT_DIR}")"
+BASE_DIR="$(dirname "$(dirname "${CURRENT_DIR}")")"
 
 # CSV source file for categories
 SOURCE_CATEGORIES_CSV_FILE="${CURRENT_DIR}/categories.csv"
diff --git a/scripts/categories.csv b/resources/data/categories.csv
similarity index 100%
rename from scripts/categories.csv
rename to resources/data/categories.csv
diff --git a/resources/ui/build_ui_resources.sh b/resources/ui/build_ui_resources.sh
new file mode 100755
index 0000000..4f365ed
--- /dev/null
+++ b/resources/ui/build_ui_resources.sh
@@ -0,0 +1,110 @@
+#! /bin/bash
+
+# Check dependencies
+command -v inkscape >/dev/null 2>&1 || { echo >&2 "I require inkscape but it's not installed. Aborting."; exit 1; }
+command -v scour >/dev/null 2>&1 || { echo >&2 "I require scour but it's not installed. Aborting."; exit 1; }
+command -v optipng >/dev/null 2>&1 || { echo >&2 "I require optipng but it's not installed. Aborting."; exit 1; }
+
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
+BASE_DIR="$(dirname "$(dirname "${CURRENT_DIR}")")"
+ASSETS_DIR="${BASE_DIR}/assets"
+
+OPTIPNG_OPTIONS="-preserve -quiet -o7"
+ICON_SIZE=192
+
+#######################################################
+
+# Game images (svg files found in `images` folder)
+AVAILABLE_GAME_IMAGES=""
+if [ -d "${CURRENT_DIR}/images" ]; then
+  AVAILABLE_GAME_IMAGES="$(find "${CURRENT_DIR}/images" -type f -name "*.svg" | awk -F/ '{print $NF}' | cut -d"." -f1 | sort)"
+fi
+
+# Skins (subfolders found in `skins` folder)
+AVAILABLE_SKINS=""
+if [ -d "${CURRENT_DIR}/skins" ]; then
+  AVAILABLE_SKINS="$(find "${CURRENT_DIR}/skins" -mindepth 1 -type d | awk -F/ '{print $NF}')"
+fi
+
+# Images per skin (svg files found recursively in `skins` folder and subfolders)
+SKIN_IMAGES=""
+if [ -d "${CURRENT_DIR}/skins" ]; then
+  SKIN_IMAGES="$(find "${CURRENT_DIR}/skins" -type f -name "*.svg" | awk -F/ '{print $NF}' | cut -d"." -f1 | sort | uniq)"
+fi
+
+#######################################################
+
+# optimize svg
+function optimize_svg() {
+  SOURCE="$1"
+
+  cp ${SOURCE} ${SOURCE}.tmp
+  scour \
+      --remove-descriptive-elements \
+      --enable-id-stripping \
+      --enable-viewboxing \
+      --enable-comment-stripping \
+      --nindent=4 \
+      --quiet \
+      -i ${SOURCE}.tmp \
+      -o ${SOURCE}
+  rm ${SOURCE}.tmp
+}
+
+# build icons
+function build_image() {
+  SOURCE="$1"
+  TARGET="$2"
+
+  echo "Building ${TARGET}"
+
+  if [ ! -f "${SOURCE}" ]; then
+    echo "Missing file: ${SOURCE}"
+    exit 1
+  fi
+
+  optimize_svg "${SOURCE}"
+
+  mkdir -p "$(dirname "${TARGET}")"
+
+  inkscape \
+      --export-width=${ICON_SIZE} \
+      --export-height=${ICON_SIZE} \
+      --export-filename=${TARGET} \
+      "${SOURCE}"
+
+  optipng ${OPTIPNG_OPTIONS} "${TARGET}"
+}
+
+function build_image_for_skin() {
+  SKIN_CODE="$1"
+
+  # skin images
+  for SKIN_IMAGE in ${SKIN_IMAGES}
+  do
+    build_image ${CURRENT_DIR}/skins/${SKIN_CODE}/${SKIN_IMAGE}.svg ${ASSETS_DIR}/skins/${SKIN_CODE}_${SKIN_IMAGE}.png
+  done
+}
+
+#######################################################
+
+# Delete existing generated images
+if [ -d "${ASSETS_DIR}/ui" ]; then
+  find ${ASSETS_DIR}/ui -type f -name "*.png" -delete
+fi
+if [ -d "${ASSETS_DIR}/skins" ]; then
+  find ${ASSETS_DIR}/skins -type f -name "*.png" -delete
+fi
+
+# build game images
+for GAME_IMAGE in ${AVAILABLE_GAME_IMAGES}
+do
+  build_image ${CURRENT_DIR}/images/${GAME_IMAGE}.svg ${ASSETS_DIR}/ui/${GAME_IMAGE}.png
+done
+
+# build skins images
+for SKIN in ${AVAILABLE_SKINS}
+do
+  build_image_for_skin "${SKIN}"
+done
+
diff --git a/icons/button_back.svg b/resources/ui/images/button_back.svg
similarity index 100%
rename from icons/button_back.svg
rename to resources/ui/images/button_back.svg
diff --git a/resources/ui/images/button_delete_saved_game.svg b/resources/ui/images/button_delete_saved_game.svg
new file mode 100644
index 0000000..ac7eefe
--- /dev/null
+++ b/resources/ui/images/button_delete_saved_game.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x=".44662" y=".89101" width="92.772" height="91.894" ry="11.689" fill="#ee7d49" stroke="#fff" stroke-width=".238"/><path d="m61.07 35.601-1.7399 27.837c-0.13442 2.1535-1.9205 3.8312-4.0781 3.8312h-16.84c-2.1576 0-3.9437-1.6777-4.0781-3.8312l-1.7399-27.837h-2.6176c-0.84621 0-1.5323-0.68613-1.5323-1.5323 0-0.84655 0.68613-1.5323 1.5323-1.5323h33.711c0.84621 0 1.5323 0.68578 1.5323 1.5323 0 0.84621-0.68613 1.5323-1.5323 1.5323zm-3.2617 0h-21.953l1.4715 26.674c0.05985 1.0829 0.95531 1.9305 2.0403 1.9305h14.929c1.085 0 1.9804-0.84757 2.0403-1.9305zm-10.977 3.0647c0.78977 0 1.4301 0.6403 1.4301 1.4301v19.614c0 0.78977-0.6403 1.4301-1.4301 1.4301s-1.4301-0.6403-1.4301-1.4301v-19.614c0-0.78977 0.6403-1.4301 1.4301-1.4301zm-6.1293 0c0.80004 0 1.4588 0.62935 1.495 1.4286l0.89647 19.719c0.03182 0.70016-0.50998 1.2933-1.2101 1.3255-0.01915 7.02e-4 -0.03831 1e-3 -0.05781 1e-3 -0.74462 0-1.3596-0.58215-1.4003-1.3261l-1.0757-19.719c-0.0407-0.74701 0.53188-1.3852 1.2786-1.4259 0.02462-0.0014 0.04926-2e-3 0.07388-2e-3zm12.259 0c0.74804 0 1.3541 0.60609 1.3541 1.3541 0 0.02462-3.28e-4 0.04926-0.0017 0.07388l-1.0703 19.618c-0.04379 0.80106-0.70597 1.4281-1.5081 1.4281-0.74804 0-1.3541-0.60609-1.3541-1.3541 0-0.02462 3.49e-4 -0.04925 0.0017-0.07388l1.0703-19.618c0.04379-0.80106 0.70597-1.4281 1.5081-1.4281zm-10.216-12.259h8.1728c2.2567 0 4.086 1.8293 4.086 4.086v2.0433h-16.344v-2.0433c0-2.2567 1.8293-4.086 4.086-4.086zm0.20453 3.0647c-0.67725 0-1.2259 0.54863-1.2259 1.2259v1.8388h10.215v-1.8388c0-0.67725-0.54863-1.2259-1.2259-1.2259z" fill="#fff" fill-rule="evenodd" stroke="#bd4812" stroke-width=".75383"/></svg>
diff --git a/resources/ui/images/button_resume_game.svg b/resources/ui/images/button_resume_game.svg
new file mode 100644
index 0000000..6ad8b64
--- /dev/null
+++ b/resources/ui/images/button_resume_game.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x=".44662" y=".89101" width="92.772" height="91.894" ry="11.689" fill="#49a1ee" stroke="#fff" stroke-width=".238"/><path d="m39.211 31.236c-0.84086-0.84489-2.9911-0.84489-2.9911 0v34.329c0 0.84594 2.1554 0.84594 2.9993 0l28.178-15.637c0.84392-0.84086 0.85812-2.2091 0.01623-3.053z" fill="#fefeff" stroke="#105ca1" stroke-linecap="round" stroke-linejoin="round" stroke-width="6.1726"/><path d="m40.355 33.714c-0.71948-0.72294-2.5594-0.72294-2.5594 0v29.373c0 0.72383 1.8442 0.72383 2.5663 0l24.11-13.38c0.7221-0.71948 0.73426-1.8902 0.01389-2.6124z" fill="#fefeff" stroke="#feffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.225"/><path d="m28.369 66.919v-37.591" fill="#105ca2" stroke="#105ca2" stroke-linecap="round" stroke-width="4.0337"/></svg>
diff --git a/icons/button_start.svg b/resources/ui/images/button_start.svg
similarity index 100%
rename from icons/button_start.svg
rename to resources/ui/images/button_start.svg
diff --git a/resources/ui/images/game_end.svg b/resources/ui/images/game_end.svg
new file mode 100644
index 0000000..fe20923
--- /dev/null
+++ b/resources/ui/images/game_end.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g transform="matrix(.17604 0 0 .17604 7.9341 1.7716)"><path d="m101.92 496.35c-1.8555 0-3.7109-0.69532-5.1484-2.0898-2.9297-2.8438-3-7.5234-0.15234-10.453l9.1875-9.4648c2.8438-2.9297 7.5234-3 10.453-0.15625s3 7.5234 0.15625 10.453l-9.1914 9.4648c-1.4492 1.4961-3.375 2.2461-5.3047 2.2461z" fill="#ff4e61"/><path d="m201.65 133.26c-1.8516 0-3.7109-0.69531-5.1445-2.0898-2.9297-2.8438-3-7.5234-0.15625-10.449l9.1914-9.4688c2.8438-2.9297 7.5195-3 10.449-0.15625s3 7.5234 0.15625 10.453l-9.1914 9.4688c-1.4492 1.4922-3.375 2.2422-5.3047 2.2422z" fill="#ff4e61"/><path d="m413.8 100.39c-1.8555 0-3.7109-0.69141-5.1484-2.0859-2.9297-2.8438-3-7.5234-0.15625-10.453l9.1914-9.4688c2.8438-2.9258 7.5234-2.9961 10.453-0.15234 2.9297 2.8398 3 7.5234 0.15625 10.449l-9.1914 9.4688c-1.4492 1.4922-3.375 2.2422-5.3047 2.2422z" fill="#5c73bc"/><path d="m413.8 463.77c-1.8555 0-3.7109-0.69532-5.1484-2.0859-2.9297-2.8438-3-7.5234-0.15625-10.453l9.1914-9.4688c2.8438-2.9258 7.5234-3 10.453-0.15625s3 7.5234 0.15625 10.453l-9.1914 9.4688c-1.4492 1.4922-3.375 2.2422-5.3047 2.2422z" fill="#fa0"/><path d="m63.07 112.91c-1.8516 0-3.7109-0.69141-5.1445-2.0859-2.9297-2.8438-3-7.5234-0.15625-10.453l9.1914-9.4687c2.8438-2.9258 7.5234-2.9961 10.453-0.15234 2.9258 2.8438 2.9961 7.5234 0.15234 10.449l-9.1914 9.4688c-1.4492 1.4922-3.375 2.2422-5.3047 2.2422z" fill="#fa0"/><path d="m12.309 278.82c-1.8516 0-3.7109-0.69141-5.1445-2.0859-2.9297-2.8438-3-7.5234-0.15625-10.453l9.1875-9.4688c2.8438-2.9297 7.5234-3 10.453-0.15625 2.9297 2.8438 3 7.5234 0.15625 10.453l-9.1914 9.4688c-1.4453 1.4922-3.375 2.2422-5.3047 2.2422z" fill="#2dc471"/><path d="m216.29 278.49-23.996 12.996c-6.2226 3.3711-13.496-2.0742-12.309-9.2148l4.582-27.523c0.47266-2.8359-0.4375-5.7266-2.4375-7.7344l-19.414-19.496c-5.0352-5.0547-2.2578-13.863 4.7031-14.906l26.824-4.0156c2.7656-0.41407 5.1524-2.1992 6.3867-4.7812l12-25.043c3.1133-6.4922 12.102-6.4922 15.215 0l11.996 25.043c1.2383 2.582 3.625 4.3672 6.3867 4.7812l26.828 4.0156c6.957 1.043 9.7344 9.8516 4.6992 14.906l-19.41 19.496c-2 2.0078-2.9141 4.8984-2.4414 7.7344l4.582 27.523c1.1914 7.1406-6.082 12.586-12.305 9.2148l-23.996-12.996c-2.4727-1.3398-5.4258-1.3398-7.8945 0z" fill="#ffd02f"/><path d="m220.24 512c-4.082 0-7.3906-3.3086-7.3906-7.3906v-115.59c0-4.082 3.3086-7.3945 7.3906-7.3945s7.3906 3.3125 7.3906 7.3945v115.59c0 4.082-3.3086 7.3906-7.3906 7.3906z" fill="#5c73bc"/><path d="m220.3 357.42h-0.11328c-4.082 0-7.3945-3.3125-7.3945-7.3945s3.3086-7.3906 7.3945-7.3906h0.11328c4.082 0 7.3906 3.3086 7.3906 7.3906s-3.3086 7.3945-7.3906 7.3945z" fill="#5c73bc"/><path d="m220.3 332h-0.14838c-4.082-0.0156-7.375-3.3398-7.3594-7.4219 0.0195-4.0742 3.3242-7.3594 7.3906-7.3594h0.14848c4.082 0.0156 7.375 3.3398 7.3594 7.4219-0.0156 4.0703-3.3242 7.3594-7.3906 7.3594z" fill="#fa0"/><path d="m87.234 230.89c-1.9297 0-3.8555-0.75-5.3047-2.2422l-79.34-81.738c-2.8438-2.9297-2.7773-7.6094 0.15234-10.449 2.9297-2.8438 7.6094-2.7734 10.453 0.15235l79.344 81.738c2.8438 2.9258 2.7734 7.6094-0.15625 10.449-1.4375 1.3945-3.293 2.0898-5.1484 2.0898z" fill="#ff4e61"/><path d="m113.95 258.5c-1.8633 0-3.7266-0.69922-5.1641-2.1055-2.9219-2.8516-2.9766-7.5312-0.125-10.453l0.082-0.082c2.8516-2.918 7.5312-2.9766 10.453-0.12109 2.9219 2.8516 2.9766 7.5312 0.12109 10.453l-0.0781 0.082c-1.4492 1.4805-3.3672 2.2266-5.2891 2.2266z" fill="#fa0"/><path d="m131.4 276.48c-1.8555 0-3.7109-0.69531-5.1484-2.0898-2.9258-2.8438-2.9961-7.5234-0.15235-10.449l0.0781-0.0859c2.8476-2.9297 7.5273-2.9961 10.453-0.15235 2.9297 2.8438 3 7.5234 0.15625 10.453l-0.082 0.082c-1.4492 1.4922-3.375 2.2422-5.3047 2.2422z" fill="#5c73bc"/><path d="m353.24 227.99c-1.8555 0-3.7109-0.69141-5.1445-2.0859-2.9297-2.8438-3-7.5234-0.15625-10.453l79.34-81.734c2.8438-2.9297 7.5234-3 10.453-0.15625 2.9297 2.8438 3 7.5234 0.15625 10.453l-79.344 81.734c-1.4492 1.4922-3.375 2.2422-5.3047 2.2422z" fill="#fa0"/><path d="m326.52 255.6c-1.9141 0-3.8242-0.73828-5.2695-2.2109l-0.082-0.082c-2.8633-2.9141-2.8203-7.5938 0.0899-10.453 2.9141-2.8633 7.5938-2.8203 10.453 0.0898l0.082 0.082c2.8594 2.9141 2.8203 7.5938-0.0937 10.453-1.4375 1.4141-3.3086 2.1211-5.1797 2.1211z" fill="#ff4e61"/><path d="m309.07 273.58c-1.9297 0-3.8555-0.75-5.3047-2.2422l-0.082-0.082c-2.8398-2.9297-2.7734-7.6094 0.15625-10.453s7.6094-2.7734 10.453 0.15234l0.082 0.082c2.8398 2.9297 2.7734 7.6094-0.15625 10.453-1.4375 1.3945-3.293 2.0898-5.1484 2.0898z" fill="#fa0"/><path d="m300.65 116.69c-1.2422 0-2.5-0.3125-3.6523-0.97266-3.5469-2.0234-4.7812-6.5391-2.7578-10.082l56.863-99.652c2.0234-3.543 6.5352-4.7773 10.082-2.7539 3.5469 2.0234 4.7812 6.5391 2.7578 10.082l-56.863 99.652c-1.3633 2.3867-3.8594 3.7266-6.4297 3.7266z" fill="#62d38f"/><path d="m281.52 150.33c-1.293 0-2.5977-0.33593-3.7891-1.0469l-0.0976-0.0586c-3.5-2.0938-4.6445-6.6328-2.5469-10.137 2.0938-3.5078 6.6328-4.6445 10.137-2.5508l0.0977 0.0586c3.5039 2.0938 4.6445 6.6328 2.5508 10.137-1.3867 2.3164-3.8359 3.5976-6.3516 3.5976z" fill="#fa0"/><path d="m269.02 172.25c-1.3008 0-2.6172-0.34375-3.8086-1.0625l-0.0977-0.0586c-3.4961-2.1094-4.6211-6.6523-2.5156-10.148 2.1094-3.4961 6.6523-4.6172 10.148-2.5117l0.0976 0.0586c3.4961 2.1094 4.6211 6.6523 2.5117 10.148-1.3867 2.3008-3.832 3.5742-6.3359 3.5742z" fill="#2dc471"/><path d="m139.96 116.69c-2.5703 0-5.0664-1.3398-6.4297-3.7305l-56.863-99.648c-2.0234-3.5469-0.78906-8.0586 2.7539-10.082 3.5469-2.0234 8.0625-0.79297 10.086 2.7539l56.863 99.648c2.0234 3.5469 0.78906 8.0625-2.7539 10.086-1.1562 0.66016-2.4141 0.97266-3.6562 0.97266z" fill="#5c73bc"/><path d="m159.09 150.33c-2.5078 0-4.957-1.2773-6.3438-3.582-2.1016-3.5-0.96875-8.043 2.5273-10.145l0.10157-0.0586c3.5-2.1016 8.0391-0.97266 10.141 2.5273 2.1055 3.5 0.97266 8.0391-2.5273 10.145l-0.0977 0.0586c-1.1914 0.71484-2.5039 1.0547-3.8008 1.0547z" fill="#ff4e61"/><path d="m171.6 172.25c-2.5 0-4.9375-1.2656-6.3281-3.5625-2.1172-3.4922-1-8.0352 2.4883-10.152l0.0977-0.0586c3.4961-2.1133 8.0391-1 10.156 2.4922 2.1133 3.4922 1 8.0352-2.4922 10.152l-0.0977 0.0586c-1.1992 0.72656-2.5195 1.0703-3.8242 1.0703z" fill="#fa0"/><path d="m402.14 357.28-15.523 11.602c-4.0234 3.0117-9.6523-0.043-9.5234-5.1641l0.5039-19.75c0.0508-2.0352-0.87109-3.9648-2.4688-5.1641l-15.508-11.621c-4.0234-3.0156-2.9453-9.4726 1.8242-10.93l18.391-5.6094c1.8906-0.57812 3.3906-2.082 4-4.0156l5.9375-18.785c1.5391-4.875 7.8359-5.8125 10.652-1.5898l10.863 16.285c1.1211 1.6758 2.9688 2.6797 4.9414 2.6797l19.18 0.0117c4.9766 4e-3 7.7891 5.8828 4.7578 9.9492l-11.676 15.672c-1.2031 1.6172-1.5586 3.7383-0.94922 5.6719l5.918 18.797c1.5312 4.875-3.0273 9.4453-7.7148 7.7344l-18.078-6.5977c-1.8594-0.67969-3.9258-0.37109-5.5273 0.82422z" fill="#ffd02f"/><path d="m261.51 512c-4.082 0-7.3906-3.3086-7.3906-7.3906 0-57.23 22.832-95.922 41.984-118.3 20.828-24.332 41.613-35.023 42.488-35.469 3.6406-1.8477 8.0898-0.39063 9.9336 3.2539 1.8438 3.6367 0.39453 8.0781-3.2422 9.9297-0.3125 0.16016-19.5 10.164-38.367 32.395-25.227 29.719-38.016 66.121-38.016 108.2 0 4.082-3.3086 7.3906-7.3906 7.3906z" fill="#ff4e61"/><path d="m102.86 397.35 11.766 15.605c3.0547 4.0469 9.2852 2.7305 10.547-2.2266l4.8633-19.113c0.5-1.9648 1.9102-3.5547 3.7695-4.2461l18.039-6.707c4.6797-1.7383 5.3906-8.25 1.207-11.016l-16.141-10.672c-1.6602-1.1016-2.6914-2.9726-2.7578-5.0039l-0.61719-19.75c-0.15625-5.1211-5.9492-7.832-9.7969-4.5859l-14.84 12.516c-1.5312 1.2891-3.5781 1.7227-5.4726 1.1562l-18.422-5.5c-4.7773-1.4258-9.0703 3.4102-7.2617 8.1836l6.9688 18.41c0.71875 1.8945 0.48438 4.0352-0.625 5.7188l-10.77 16.348c-2.793 4.2422 0.34375 9.9375 5.3125 9.6445l19.145-1.1406c1.9727-0.11719 3.875 0.77343 5.0859 2.3789z" fill="#ffd02f"/><path d="m179.02 512c-4.082 0-7.3906-3.3086-7.3906-7.3906 0-30.059-6.6797-57.559-19.852-81.734-1.9531-3.5859-0.62891-8.0742 2.957-10.027 3.5859-1.9531 8.0742-0.62891 10.027 2.9531 14.363 26.375 21.648 56.254 21.648 88.809 0 4.082-3.3086 7.3906-7.3906 7.3906z" fill="#fa0"/><path d="m268.93 55.898c0-11.285-8.8828-20.434-19.836-20.434-10.957 0-19.836 9.1484-19.836 20.434 0 11.285 8.8789 20.438 19.836 20.438 10.953 0 19.836-9.1523 19.836-20.438z" fill="#ffd02f"/><path d="m373.08 446.81c0-11.285-8.8789-20.434-19.832-20.434-10.957 0-19.836 9.1484-19.836 20.434s8.8789 20.434 19.836 20.434c10.953 0 19.832-9.1484 19.832-20.434z" fill="#5c73bc"/><path d="m44.129 450.86c0-9.0508-7.1211-16.387-15.91-16.387-8.7852 0-15.906 7.3359-15.906 16.387 0 9.0547 7.1211 16.391 15.906 16.391 8.7891 0 15.91-7.3359 15.91-16.391z" fill="#62d38f"/><path d="m88.172 288.35c0-9.0508-7.1211-16.387-15.91-16.387-8.7852 0-15.906 7.3359-15.906 16.387s7.1211 16.391 15.906 16.391c8.7891 0 15.91-7.3398 15.91-16.391z" fill="#5c73bc"/><g fill="#ff4e61"><path d="m210.84 16.391c0-9.0547-7.1211-16.391-15.906-16.391-8.7891 0-15.91 7.3359-15.91 16.391 0 9.0508 7.1211 16.387 15.91 16.387 8.7852 0 15.906-7.3359 15.906-16.387z"/><path d="m365.23 152.88c0-9.0508-7.125-16.391-15.91-16.391-8.7852 0-15.91 7.3398-15.91 16.391s7.125 16.387 15.91 16.387c8.7852 0 15.91-7.3359 15.91-16.387z"/><path d="m139.96 32.746c-1.8555 0-3.7109-0.69141-5.1484-2.0898-2.9297-2.8438-3-7.5195-0.15625-10.449l9.1914-9.4688c2.8438-2.9297 7.5234-3 10.449-0.15625 2.9297 2.8438 3 7.5234 0.15625 10.453l-9.1875 9.4688c-1.4492 1.4922-3.3789 2.2422-5.3047 2.2422z"/></g></g></svg>
diff --git a/icons/placeholder.svg b/resources/ui/images/placeholder.svg
similarity index 100%
rename from icons/placeholder.svg
rename to resources/ui/images/placeholder.svg
-- 
GitLab