diff --git a/README.md b/README.md
index 594b8fe7db488b8c159a3ad855953f3cd32e0571..5359b042f597ebc085cd983f9ca59ef71e339f7e 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
 # Solitaire Game
+
+Simple, easy, with 4 available layouts.
diff --git a/android/gradle.properties b/android/gradle.properties
index 30298b3b3f04073678e48519b8c043edba635df8..a392afe6f07c995cecb66b32859bb129bf2a0055 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -1,5 +1,5 @@
 org.gradle.jvmargs=-Xmx1536M
 android.useAndroidX=true
 android.enableJetifier=true
-app.versionName=0.0.18
-app.versionCode=18
+app.versionName=0.1.0
+app.versionCode=19
diff --git a/assets/translations/en.json b/assets/translations/en.json
index 13da5fcbf5903240f481642c2ef432873c7a3d7c..daff9b7f06d928cf6547c4e7d90f7f28be18339b 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -1,14 +1,12 @@
 {
   "app_name": "Solitaire",
 
-  "bottom_nav_home": "Game",
-  "bottom_nav_settings": "Settings",
-  "bottom_nav_about": "About",
-
   "settings_title": "Settings",
   "settings_label_theme": "Theme mode",
 
   "about_title": "About",
   "about_content": "Solitaire.",
-  "about_version": "Version: {version}"
+  "about_version": "Version: {version}",
+
+  "": ""
 }
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
index 0d43876a4b6ebfadf9222ed4ac88d5c53d5064ef..ebc19d92280150d15e4c787a22887f6ce74ea66c 100644
--- a/assets/translations/fr.json
+++ b/assets/translations/fr.json
@@ -1,14 +1,12 @@
 {
   "app_name": "Solitaire",
 
-  "bottom_nav_home": "Jeu",
-  "bottom_nav_settings": "Réglages",
-  "bottom_nav_about": "Infos",
-
   "settings_title": "Réglages",
   "settings_label_theme": "Thème de couleurs",
 
   "about_title": "Informations",
   "about_content": "Solitaire.",
-  "about_version": "Version : {version}"
+  "about_version": "Version : {version}",
+
+  "": ""
 }
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
Binary files /dev/null and b/assets/ui/button_delete_saved_game.png differ
diff --git a/assets/ui/button_resume_game.png b/assets/ui/button_resume_game.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2ea0a02d05e42377eb551a4b51428b511a32f5d
Binary files /dev/null and b/assets/ui/button_resume_game.png differ
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_fail.png b/assets/ui/game_fail.png
new file mode 100644
index 0000000000000000000000000000000000000000..93f2801f9d6bb2ce508e1293cd64d6ff2e9970ec
Binary files /dev/null and b/assets/ui/game_fail.png differ
diff --git a/assets/icons/game_win.png b/assets/ui/game_win.png
similarity index 100%
rename from assets/icons/game_win.png
rename to assets/ui/game_win.png
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/19.txt b/fastlane/metadata/android/en-US/changelogs/19.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d4afd512e55b3fd8ffbfd795adb9b00832e5aaef
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/19.txt
@@ -0,0 +1 @@
+Improve/normalize game architecture.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/19.txt b/fastlane/metadata/android/fr-FR/changelogs/19.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6a9871a5eb8eb3c6e9106520f1cbf1f39f9e5ef7
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/19.txt
@@ -0,0 +1 @@
+Amélioration/normalisation de l'architecture du jeu.
diff --git a/lib/config/default_game_settings.dart b/lib/config/default_game_settings.dart
index 6ac27dcf613094e37f638ebe8d69573e4219deca..65486565481923ce8d0a0280446c85ccb858198b 100644
--- a/lib/config/default_game_settings.dart
+++ b/lib/config/default_game_settings.dart
@@ -1,4 +1,4 @@
-import 'package:solitaire/utils/tools.dart';
+import 'package:solitaire/utils/tools.dart'; 
 
 class DefaultGameSettings {
   // available game parameters codes
@@ -21,6 +21,7 @@ class DefaultGameSettings {
   // layout: default value
   static const String defaultLayoutValue = layoutValueEnglish;
 
+  // available values from parameter code
   static List<String> getAvailableValues(String parameterCode) {
     switch (parameterCode) {
       case parameterCodeLayout:
@@ -30,4 +31,9 @@ class DefaultGameSettings {
     printlog('Did not find any available value for game parameter "$parameterCode".');
     return [];
   }
+
+  // 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 622a8b66d293815ec6ce9d50f7cefd9701606f1d..5e6ddc08eaa65f6837a222def09f0bcf249de698 100644
--- a/lib/config/default_global_settings.dart
+++ b/lib/config/default_global_settings.dart
@@ -1,4 +1,4 @@
-import 'package:solitaire/utils/tools.dart';
+import 'package:solitaire/utils/tools.dart'; 
 
 class DefaultGlobalSettings {
   // available global parameters codes
@@ -15,6 +15,7 @@ class DefaultGlobalSettings {
   // skin: default value
   static const String defaultSkinValue = skinValueDefault;
 
+  // available values from parameter code
   static List<String> getAvailableValues(String parameterCode) {
     switch (parameterCode) {
       case parameterCodeSkin:
@@ -24,4 +25,9 @@ class DefaultGlobalSettings {
     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 3d2fcfacf3e2ca175870530e2f4e33f74264bb79..dcb8a6fe45d9fe20f244e449a89634b4c692a0ae 100644
--- a/lib/config/menu.dart
+++ b/lib/config/menu.dart
@@ -6,12 +6,10 @@ import 'package:solitaire/ui/screens/page_game.dart';
 import 'package:solitaire/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 be390348c7868e7c63387df13e13c46de43f8a23..74f532fd5abf693979118609564d29167e902009 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 aba2472b6c5e923a383e4da46abd8a1611a43e88..1ce79e07584c3642b3614dce0c50df0b279bdcb8 100644
--- a/lib/cubit/game_cubit.dart
+++ b/lib/cubit/game_cubit.dart
@@ -2,10 +2,10 @@ import 'package:equatable/equatable.dart';
 import 'package:flutter/material.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 
-import 'package:solitaire/models/cell_location.dart';
-import 'package:solitaire/models/game.dart';
-import 'package:solitaire/models/settings_game.dart';
-import 'package:solitaire/models/settings_global.dart';
+import 'package:solitaire/models/game/cell_location.dart';
+import 'package:solitaire/models/game/game.dart';
+import 'package:solitaire/models/settings/settings_game.dart';
+import 'package:solitaire/models/settings/settings_global.dart';
 import 'package:solitaire/utils/tools.dart';
 
 part 'game_state.dart';
@@ -13,7 +13,7 @@ part 'game_state.dart';
 class GameCubit extends HydratedCubit<GameState> {
   GameCubit()
       : super(GameState(
-          currentGame: Game.createNull(),
+          currentGame: Game.createEmpty(),
         ));
 
   void updateState(Game game) {
@@ -24,11 +24,17 @@ class GameCubit extends HydratedCubit<GameState> {
 
   void refresh() {
     final Game game = Game(
+      // Settings
       gameSettings: state.currentGame.gameSettings,
       globalSettings: state.currentGame.globalSettings,
-      board: state.currentGame.board,
+      // State
       isRunning: state.currentGame.isRunning,
+      isStarted: state.currentGame.isStarted,
       isFinished: state.currentGame.isFinished,
+      animationInProgress: state.currentGame.animationInProgress,
+      // Base data
+      board: state.currentGame.board,
+      // Game data
       movesCount: state.currentGame.movesCount,
       remainingPegsCount: state.currentGame.remainingPegsCount,
       allowedMovesCount: state.currentGame.allowedMovesCount,
@@ -42,7 +48,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,
     );
@@ -62,12 +69,24 @@ 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 updatePegValue(CellLocation location, bool hasPeg) {
     state.currentGame.board.cells[location.row][location.col].hasPeg = hasPeg;
     refresh();
   }
 
   void incrementMovesCount() {
+    state.currentGame.isStarted = true;
     state.currentGame.movesCount++;
     refresh();
   }
@@ -111,7 +130,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 3fd161a0915313722b7a15c55c7cf538a7e3b6e1..00e211668c3269255926939324355792abd61c41 100644
--- a/lib/cubit/game_state.dart
+++ b/lib/cubit/game_state.dart
@@ -12,8 +12,4 @@ class GameState extends Equatable {
   List<dynamic> get props => <dynamic>[
         currentGame,
       ];
-
-  Map<String, dynamic> get values => <String, dynamic>{
-        'currentGame': currentGame,
-      };
 }
diff --git a/lib/cubit/settings_game_cubit.dart b/lib/cubit/settings_game_cubit.dart
index 7399314684c139542eb3559b67e6dceeb9641bde..18848abeb795ba9358a804c672234f011f1d8c77 100644
--- a/lib/cubit/settings_game_cubit.dart
+++ b/lib/cubit/settings_game_cubit.dart
@@ -3,8 +3,7 @@ import 'package:flutter/material.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 import 'package:solitaire/config/default_game_settings.dart';
-import 'package:solitaire/models/settings_game.dart';
-import 'package:solitaire/utils/tools.dart';
+import 'package:solitaire/models/settings/settings_game.dart';
 
 part 'settings_game_state.dart';
 
@@ -28,14 +27,12 @@ class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
       case DefaultGameSettings.parameterCodeLayout:
         return GameSettings.getLayoutValueFromUnsafe(state.settings.layout);
     }
+
     return '';
   }
 
   void setParameterValue(String code, String value) {
-    printlog('GameSettingsCubit.setParameterValue');
-    printlog('code: $code  / value: $value');
-
-    String layout = code == DefaultGameSettings.parameterCodeLayout
+    final String layout = code == DefaultGameSettings.parameterCodeLayout
         ? value
         : getParameterValue(DefaultGameSettings.parameterCodeLayout);
 
@@ -46,7 +43,7 @@ class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
 
   @override
   GameSettingsState? fromJson(Map<String, dynamic> json) {
-    String layout = json[DefaultGameSettings.parameterCodeLayout] as String;
+    final String layout = json[DefaultGameSettings.parameterCodeLayout] as String;
 
     return GameSettingsState(
       settings: GameSettings(
diff --git a/lib/cubit/settings_game_state.dart b/lib/cubit/settings_game_state.dart
index b773dc69be12673b158e880e2d7e6e7bec465506..5acd85b44ba541e1c5e9c26af1c4be26a385b9ed 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 274c113cff2bfa94e9e3ea492e9359ca11d149ca..a4042135ab4420ed235b635b01ca14ba596f6dfb 100644
--- a/lib/cubit/settings_global_cubit.dart
+++ b/lib/cubit/settings_global_cubit.dart
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 import 'package:solitaire/config/default_global_settings.dart';
-import 'package:solitaire/models/settings_global.dart';
+import 'package:solitaire/models/settings/settings_global.dart';
 
 part 'settings_global_state.dart';
 
diff --git a/lib/cubit/settings_global_state.dart b/lib/cubit/settings_global_state.dart
index 4e4fbdf707b4e805f2092d0ca6a68a2de1c957c6..ebcddd700f252257223ca8e16c85202b04f3ff24 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/main.dart b/lib/main.dart
index d507c2d5d0495158dbf6f02d6a0fb3ba4a6faaa8..48897d6132ef277ec095c43263ee0e9643de8662 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -2,11 +2,13 @@ import 'dart:io';
 
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:hive/hive.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 import 'package:path_provider/path_provider.dart';
 
+import 'package:solitaire/config/default_global_settings.dart';
 import 'package:solitaire/config/theme.dart';
 import 'package:solitaire/cubit/game_cubit.dart';
 import 'package:solitaire/cubit/nav_cubit.dart';
@@ -25,18 +27,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 +45,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 +79,36 @@ class MyApp extends StatelessWidget {
       ),
     );
   }
+
+  List<String> getImagesAssets() {
+    final List<String> assets = [];
+
+    final List<String> gameImages = [
+      'button_back',
+      'button_delete_saved_game',
+      'button_resume_game',
+      'button_start',
+      'game_fail',
+      'game_win',
+      'placeholder',
+    ];
+
+    for (String image in gameImages) {
+      assets.add('assets/ui/$image.png');
+    }
+
+    final List<String> skinImages = [
+      'board',
+      'hole',
+      'peg',
+    ];
+
+    for (String skin in DefaultGlobalSettings.allowedSkinValues) {
+      for (String image in skinImages) {
+        assets.add('assets/skins/${skin}_$image.png');
+      }
+    }
+
+    return assets;
+  }
 }
diff --git a/lib/models/board.dart b/lib/models/game/board.dart
similarity index 96%
rename from lib/models/board.dart
rename to lib/models/game/board.dart
index eb1ce73259a307e58116df681052bb81b551d6b2..2834c6d212e0ba45b869c7309547db07339dfda6 100644
--- a/lib/models/board.dart
+++ b/lib/models/game/board.dart
@@ -1,7 +1,7 @@
 import 'package:solitaire/data/game_data.dart';
-import 'package:solitaire/models/cell.dart';
-import 'package:solitaire/models/cell_location.dart';
-import 'package:solitaire/models/settings_game.dart';
+import 'package:solitaire/models/game/cell.dart';
+import 'package:solitaire/models/game/cell_location.dart';
+import 'package:solitaire/models/settings/settings_game.dart';
 import 'package:solitaire/utils/tools.dart';
 
 typedef BoardCells = List<List<Cell>>;
diff --git a/lib/models/cell.dart b/lib/models/game/cell.dart
similarity index 86%
rename from lib/models/cell.dart
rename to lib/models/game/cell.dart
index 127c3006372ae606f25206aa7ef1209ec78a1ecc..91b6d5e59931d314787fae7408fbec1009501c88 100644
--- a/lib/models/cell.dart
+++ b/lib/models/game/cell.dart
@@ -1,5 +1,5 @@
-import 'package:solitaire/models/cell_location.dart';
-import 'package:solitaire/utils/tools.dart';
+import 'package:solitaire/models/game/cell_location.dart';
+import 'package:solitaire/utils/tools.dart'; 
 
 class Cell {
   Cell({
diff --git a/lib/models/cell_location.dart b/lib/models/game/cell_location.dart
similarity index 92%
rename from lib/models/cell_location.dart
rename to lib/models/game/cell_location.dart
index f9b90220feff4828ca6fa846d4933cac195608b2..f0fc583307968c15324e589410255bd674a27f0a 100644
--- a/lib/models/cell_location.dart
+++ b/lib/models/game/cell_location.dart
@@ -1,4 +1,4 @@
-import 'package:solitaire/utils/tools.dart';
+import 'package:solitaire/utils/tools.dart'; 
 
 class CellLocation {
   final int col;
diff --git a/lib/models/game.dart b/lib/models/game/game.dart
similarity index 60%
rename from lib/models/game.dart
rename to lib/models/game/game.dart
index 009ff4f3b07ce3370c5b6764f89e8c3f2256fea2..76f09e526f76c6675e3635dfd2a832f591861521 100644
--- a/lib/models/game.dart
+++ b/lib/models/game/game.dart
@@ -1,37 +1,54 @@
-import 'package:solitaire/models/board.dart';
-import 'package:solitaire/models/cell.dart';
-import 'package:solitaire/models/settings_game.dart';
-import 'package:solitaire/models/settings_global.dart';
+import 'package:solitaire/models/game/board.dart';
+import 'package:solitaire/models/game/cell.dart';
+import 'package:solitaire/models/settings/settings_game.dart';
+import 'package:solitaire/models/settings/settings_global.dart';
 import 'package:solitaire/utils/tools.dart';
 
 class Game {
   Game({
+    // Settings
     required this.gameSettings,
     required this.globalSettings,
-    required this.board,
+
+    // State
     this.isRunning = false,
+    this.isStarted = false,
     this.isFinished = false,
+    this.animationInProgress = false,
+
+    // Base data
+    required this.board,
+
+    // Game data
     this.movesCount = 0,
     this.remainingPegsCount = 0,
     this.allowedMovesCount = 0,
   });
 
+  // Settings
   final GameSettings gameSettings;
   final GlobalSettings globalSettings;
 
-  bool isRunning = false;
-  bool isFinished = false;
+  // State
+  bool isRunning;
+  bool isStarted;
+  bool isFinished;
+  bool animationInProgress;
 
-  Board board;
+  // Base data
+  final Board board;
 
-  int movesCount = 0;
-  int remainingPegsCount = 0;
-  int allowedMovesCount = 0;
+  // Game data
+  int movesCount;
+  int remainingPegsCount;
+  int allowedMovesCount;
 
-  factory Game.createNull() {
+  factory Game.createEmpty() {
     return Game(
+      // Settings
       gameSettings: GameSettings.createDefault(),
       globalSettings: GlobalSettings.createDefault(),
+      // Base data
       board: Board.createEmpty(),
     );
   }
@@ -40,22 +57,25 @@ class Game {
     GameSettings? gameSettings,
     GlobalSettings? globalSettings,
   }) {
-    GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
-    GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
+    final GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
+    final GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
 
     return Game(
+      // Settings
       gameSettings: newGameSettings,
       globalSettings: newGlobalSettings,
-      board: Board.createNew(
-        gameSettings: newGameSettings,
-      ),
+      // State
       isRunning: true,
+      // Base data
+      board: Board.createNew(gameSettings: newGameSettings),
     );
   }
 
-  int get boardSize => board.boardSize;
+  bool get canBeResumed => isStarted && !isFinished;
+
+  bool get gameWon => isRunning && isStarted && isFinished;
 
-  bool get gameWon => (isFinished && (remainingPegsCount == 1));
+  int get boardSize => board.boardSize;
 
   List<Cell> listRemainingPegs() {
     final List<Cell> pegs = [];
@@ -106,19 +126,21 @@ class Game {
   void dump() {
     printlog('');
     printlog('## Current game dump:');
-    printlog('');
+    printlog('$Game:');
+    printlog('  Settings');
     gameSettings.dump();
     globalSettings.dump();
-    printlog('');
-    printlog('');
-    printlog('$Game: ');
-    printlog('  isRunning: $isRunning');
-    printlog('  isFinished: $isFinished');
-    printlog('  movesCount: $movesCount');
-    printlog('  remainingPegsCount: $remainingPegsCount');
-    printlog('  allowedMovesCount: $allowedMovesCount');
-    printlog('');
+    printlog('  State');
+    printlog('    isRunning: $isRunning');
+    printlog('    isStarted: $isStarted');
+    printlog('    isFinished: $isFinished');
+    printlog('    animationInProgress: $animationInProgress');
+    printlog('  Base data');
     board.dump();
+    printlog('  Game data');
+    printlog('    movesCount: $movesCount');
+    printlog('    remainingPegsCount: $remainingPegsCount');
+    printlog('    allowedMovesCount: $allowedMovesCount');
     printlog('');
   }
 
@@ -129,11 +151,17 @@ class Game {
 
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
+      // Settings
       'gameSettings': gameSettings.toJson(),
       'globalSettings': globalSettings.toJson(),
-      'board': board.toJson(),
+      // State
       'isRunning': isRunning,
+      'isStarted': isStarted,
       'isFinished': isFinished,
+      'animationInProgress': animationInProgress,
+      // Base data
+      'board': board.toJson(),
+      // Game data
       'movesCount': movesCount,
       'remainingPegsCount': remainingPegsCount,
       'allowedMovesCount': allowedMovesCount,
diff --git a/lib/models/settings_game.dart b/lib/models/settings/settings_game.dart
similarity index 91%
rename from lib/models/settings_game.dart
rename to lib/models/settings/settings_game.dart
index cb00bc94a4ce5dab5065076202e0215e1cd21b97..006584e7922673a67c471deec0aa9427230a4cf0 100644
--- a/lib/models/settings_game.dart
+++ b/lib/models/settings/settings_game.dart
@@ -1,5 +1,5 @@
 import 'package:solitaire/config/default_game_settings.dart';
-import 'package:solitaire/utils/tools.dart';
+import 'package:solitaire/utils/tools.dart'; 
 
 class GameSettings {
   final String layout;
@@ -23,7 +23,7 @@ class GameSettings {
   }
 
   void dump() {
-    printlog('$GameSettings: ');
+    printlog('$GameSettings:');
     printlog('  ${DefaultGameSettings.parameterCodeLayout}: $layout');
     printlog('');
   }
diff --git a/lib/models/settings_global.dart b/lib/models/settings/settings_global.dart
similarity index 91%
rename from lib/models/settings_global.dart
rename to lib/models/settings/settings_global.dart
index dd4b7c86673d9ed4e43f5cdbb0f8e9a0bd10f851..e67b92d4293993d8516a9345a6a7a112a910deca 100644
--- a/lib/models/settings_global.dart
+++ b/lib/models/settings/settings_global.dart
@@ -1,5 +1,5 @@
 import 'package:solitaire/config/default_global_settings.dart';
-import 'package:solitaire/utils/tools.dart';
+import 'package:solitaire/utils/tools.dart'; 
 
 class GlobalSettings {
   String skin;
@@ -23,7 +23,7 @@ class GlobalSettings {
   }
 
   void dump() {
-    printlog('$GlobalSettings: ');
+    printlog('$GlobalSettings:');
     printlog('  ${DefaultGlobalSettings.parameterCodeSkin}: $skin');
     printlog('');
   }
diff --git a/lib/models/types.dart b/lib/models/types.dart
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/lib/ui/game/game_end.dart b/lib/ui/game/game_end.dart
new file mode 100644
index 0000000000000000000000000000000000000000..7f0d3f7a80389a9aebb2602e32faef679440f27b
--- /dev/null
+++ b/lib/ui/game/game_end.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:solitaire/cubit/game_cubit.dart';
+import 'package:solitaire/models/game/game.dart';
+import 'package:solitaire/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;
+
+        final Image decorationImage = Image(
+          image: AssetImage(
+              currentGame.gameWon ? 'assets/ui/game_win.png' : 'assets/ui/game_fail.png'),
+          fit: BoxFit.fill,
+        );
+
+        return Container(
+          margin: const EdgeInsets.all(2),
+          padding: const EdgeInsets.all(2),
+          child: Table(
+            defaultColumnWidth: const IntrinsicColumnWidth(),
+            children: [
+              TableRow(
+                children: [
+                  Column(
+                    children: [decorationImage],
+                  ),
+                  Column(
+                    children: [
+                      currentGame.animationInProgress == true
+                          ? decorationImage
+                          : const QuitGameButton()
+                    ],
+                  ),
+                  Column(
+                    children: [decorationImage],
+                  ),
+                ],
+              ),
+            ],
+          ),
+        );
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/game/indicator_top.dart b/lib/ui/game/game_top.dart
similarity index 91%
rename from lib/ui/widgets/game/indicator_top.dart
rename to lib/ui/game/game_top.dart
index bc66f795fb1c03308aa1a4492367d87c9cb89dd4..b6319e7591694b2d57ac850f64c12a9999a1fb92 100644
--- a/lib/ui/widgets/game/indicator_top.dart
+++ b/lib/ui/game/game_top.dart
@@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:solitaire/cubit/game_cubit.dart';
-import 'package:solitaire/models/game.dart';
+import 'package:solitaire/models/game/game.dart';
 
-class TopIndicator extends StatelessWidget {
-  const TopIndicator({super.key});
+class GameTopWidget extends StatelessWidget {
+  const GameTopWidget({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/helpers/app_titles.dart b/lib/ui/helpers/app_titles.dart
new file mode 100644
index 0000000000000000000000000000000000000000..b98107b12fabc3114ebfbec994166b588abcf1ad
--- /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/helpers/outlined_text_widget.dart b/lib/ui/helpers/outlined_text_widget.dart
new file mode 100644
index 0000000000000000000000000000000000000000..0fbd95533de0b23f2c599134eac9447a09a98e31
--- /dev/null
+++ b/lib/ui/helpers/outlined_text_widget.dart
@@ -0,0 +1,51 @@
+import 'package:flutter/material.dart';
+
+import 'package:solitaire/utils/color_extensions.dart';
+
+class OutlinedText extends StatelessWidget {
+  const OutlinedText({
+    super.key,
+    required this.text,
+    required this.fontSize,
+    required this.textColor,
+    this.outlineColor,
+  });
+
+  final String text;
+  final double fontSize;
+  final Color textColor;
+  final Color? outlineColor;
+
+  @override
+  Widget build(BuildContext context) {
+    final double delta = fontSize / 30;
+
+    return Text(
+      text,
+      style: TextStyle(
+        inherit: true,
+        fontSize: fontSize,
+        fontWeight: FontWeight.w600,
+        color: textColor,
+        shadows: [
+          Shadow(
+            offset: Offset(-delta, -delta),
+            color: outlineColor ?? textColor.darken(),
+          ),
+          Shadow(
+            offset: Offset(delta, -delta),
+            color: outlineColor ?? textColor.darken(),
+          ),
+          Shadow(
+            offset: Offset(delta, delta),
+            color: outlineColor ?? textColor.darken(),
+          ),
+          Shadow(
+            offset: Offset(-delta, delta),
+            color: outlineColor ?? textColor.darken(),
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/ui/layouts/game_layout.dart b/lib/ui/layouts/game_layout.dart
new file mode 100644
index 0000000000000000000000000000000000000000..36356465d23ec0f96e49ae1a412c4950aefaea1a
--- /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:solitaire/cubit/game_cubit.dart';
+import 'package:solitaire/models/game/game.dart';
+import 'package:solitaire/ui/game/game_end.dart';
+import 'package:solitaire/ui/game/game_top.dart';
+import 'package:solitaire/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 55%
rename from lib/ui/widgets/parameters.dart
rename to lib/ui/layouts/parameters_layout.dart
index 11b080d42b81d7c750212791a67537e8979818ba..d0520208a67def5f488ffb2f41d119f543ad5857 100644
--- a/lib/ui/widgets/parameters.dart
+++ b/lib/ui/layouts/parameters_layout.dart
@@ -5,11 +5,16 @@ import 'package:solitaire/config/default_game_settings.dart';
 import 'package:solitaire/config/default_global_settings.dart';
 import 'package:solitaire/cubit/settings_game_cubit.dart';
 import 'package:solitaire/cubit/settings_global_cubit.dart';
-import 'package:solitaire/ui/painters/parameter_painter.dart';
-import 'package:solitaire/ui/widgets/button_game_start_new.dart';
+import 'package:solitaire/ui/parameters/parameter_image.dart';
+import 'package:solitaire/ui/parameters/parameter_painter.dart';
+import 'package:solitaire/ui/widgets/actions/button_delete_saved_game.dart';
+import 'package:solitaire/ui/widgets/actions/button_game_start_new.dart';
+import 'package:solitaire/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
@@ -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 0000000000000000000000000000000000000000..fc4b576f85b01158b74548400d11a4d027c57fbe
--- /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 94%
rename from lib/ui/painters/parameter_painter.dart
rename to lib/ui/parameters/parameter_painter.dart
index 4ed92d7734eb935bbe24925a49fcab2864476d33..9b86f6faac98cecffe804d246ce42f10df91d272 100644
--- a/lib/ui/painters/parameter_painter.dart
+++ b/lib/ui/parameters/parameter_painter.dart
@@ -4,11 +4,11 @@ import 'package:flutter/material.dart';
 
 import 'package:solitaire/config/default_game_settings.dart';
 import 'package:solitaire/data/game_data.dart';
-import 'package:solitaire/models/board.dart';
-import 'package:solitaire/models/cell.dart';
-import 'package:solitaire/models/cell_location.dart';
-import 'package:solitaire/models/settings_game.dart';
-import 'package:solitaire/models/settings_global.dart';
+import 'package:solitaire/models/game/board.dart';
+import 'package:solitaire/models/game/cell.dart';
+import 'package:solitaire/models/game/cell_location.dart';
+import 'package:solitaire/models/settings/settings_game.dart';
+import 'package:solitaire/models/settings/settings_global.dart';
 import 'package:solitaire/utils/tools.dart';
 
 class ParameterPainter extends CustomPainter {
diff --git a/lib/ui/screens/page_about.dart b/lib/ui/screens/page_about.dart
index f63e1530869dd9aaf2a093e2610f326c3050589f..d4e5947305863d030a6888e0055a31761f696ace 100644
--- a/lib/ui/screens/page_about.dart
+++ b/lib/ui/screens/page_about.dart
@@ -2,7 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:package_info_plus/package_info_plus.dart';
 
-import 'package:solitaire/ui/widgets/helpers/app_header.dart';
+import 'package:solitaire/ui/helpers/app_titles.dart';
 
 class PageAbout extends StatelessWidget {
   const PageAbout({super.key});
@@ -17,7 +17,7 @@ class PageAbout extends StatelessWidget {
         mainAxisSize: MainAxisSize.max,
         children: <Widget>[
           const SizedBox(height: 8),
-          const AppHeader(text: 'about_title'),
+          const AppTitle(text: 'about_title'),
           const Text('about_content').tr(),
           FutureBuilder<PackageInfo>(
             future: PackageInfo.fromPlatform(),
diff --git a/lib/ui/screens/page_game.dart b/lib/ui/screens/page_game.dart
index 287a3832dc66424363f99183602f6b3faf4785fd..2a5509f9b02d5473ab874711470ec6398ac95738 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:solitaire/cubit/game_cubit.dart';
-import 'package:solitaire/ui/widgets/game/game_widget.dart';
-import 'package:solitaire/ui/widgets/parameters.dart';
+import 'package:solitaire/models/game/game.dart';
+import 'package:solitaire/ui/layouts/game_layout.dart';
+import 'package:solitaire/ui/layouts/parameters_layout.dart';
 
 class PageGame extends StatelessWidget {
   const PageGame({super.key});
@@ -12,7 +13,11 @@ class PageGame extends StatelessWidget {
   Widget build(BuildContext context) {
     return BlocBuilder<GameCubit, GameState>(
       builder: (BuildContext context, GameState gameState) {
-        return gameState.currentGame.isRunning ? const GameWidget() : const Parameters();
+        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 ae65ab921d0840b9d014f098187ae4b02076a9b2..868ad1a9b43d7267c78197fc3207c545c0545896 100644
--- a/lib/ui/screens/page_settings.dart
+++ b/lib/ui/screens/page_settings.dart
@@ -1,7 +1,7 @@
 import 'package:flutter/material.dart';
 
-import 'package:solitaire/ui/widgets/helpers/app_header.dart';
-import 'package:solitaire/ui/widgets/settings/settings_form.dart';
+import 'package:solitaire/ui/helpers/app_titles.dart';
+import 'package:solitaire/ui/settings/settings_form.dart';
 
 class PageSettings extends StatelessWidget {
   const PageSettings({super.key});
@@ -16,7 +16,7 @@ class PageSettings extends StatelessWidget {
         mainAxisSize: MainAxisSize.max,
         children: <Widget>[
           SizedBox(height: 8),
-          AppHeader(text: 'settings_title'),
+          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 91e9fd50423ac3bdadcccfde1abb3d0939e0dcba..5b03fe6f88f5a888d71f852fd9291f2ae9ab7da1 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:solitaire/ui/widgets/settings/theme_card.dart';
+import 'package:solitaire/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 c57f5c2ce6db287ee0efbcde7f0f0dfd7afd59fd..eb5336eb8006db4e0df6a13de9e93d9aac70d4c3 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 0000000000000000000000000000000000000000..df484d7423e312369cfe6c5fb40ae3bd01e2a21d
--- /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:solitaire/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 0000000000000000000000000000000000000000..a90e6cbc638cc5c4d58ba14c9d2e10f57e7c5563
--- /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:solitaire/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 cd4b8f01caebb1ed5195e2e702b62d01806cfc01..e4a4b593bc1740b4e5523c206a39e41bc15b06c2 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 0000000000000000000000000000000000000000..d93fcd4d5850e003cc7c993f550618d83481d84a
--- /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:solitaire/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/tileset.dart b/lib/ui/widgets/game/game_board.dart
similarity index 90%
rename from lib/ui/widgets/game/tileset.dart
rename to lib/ui/widgets/game/game_board.dart
index 5462a796ad34ad7fc042d41dea00fabc0faf35fd..a05d73b5b8f96b0925b79e115afe6b72e487402c 100644
--- a/lib/ui/widgets/game/tileset.dart
+++ b/lib/ui/widgets/game/game_board.dart
@@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:solitaire/cubit/game_cubit.dart';
-import 'package:solitaire/models/board.dart';
+import 'package:solitaire/models/game/board.dart';
 import 'package:solitaire/ui/widgets/game/tile_widget.dart';
 
-class Tileset extends StatelessWidget {
-  const Tileset({super.key});
+class GameBoardWidget extends StatelessWidget {
+  const GameBoardWidget({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/widgets/game/game_widget.dart b/lib/ui/widgets/game/game_widget.dart
deleted file mode 100644
index e2c7cafae7bcbca07d3309d47a967452329e4b1b..0000000000000000000000000000000000000000
--- a/lib/ui/widgets/game/game_widget.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'package:solitaire/cubit/game_cubit.dart';
-import 'package:solitaire/models/game.dart';
-import 'package:solitaire/ui/widgets/game/indicator_top.dart';
-import 'package:solitaire/ui/widgets/game/message_game_end.dart';
-import 'package:solitaire/ui/widgets/game/tileset.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;
-
-        final bool gameIsFinished = currentGame.isFinished;
-
-        return Column(
-          mainAxisAlignment: MainAxisAlignment.start,
-          crossAxisAlignment: CrossAxisAlignment.center,
-          children: [
-            const SizedBox(height: 8),
-            const TopIndicator(),
-            const SizedBox(height: 2),
-            const Expanded(
-              child: Tileset(),
-            ),
-            const SizedBox(height: 2),
-            gameIsFinished ? const EndGameMessage() : const SizedBox(height: 2),
-          ],
-        );
-      },
-    );
-  }
-}
diff --git a/lib/ui/widgets/game/message_game_end.dart b/lib/ui/widgets/game/message_game_end.dart
deleted file mode 100644
index b1b4faa4d361a8c7ddff40d35028c381d2378c58..0000000000000000000000000000000000000000
--- a/lib/ui/widgets/game/message_game_end.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'package:solitaire/cubit/game_cubit.dart';
-import 'package:solitaire/models/game.dart';
-
-class EndGameMessage extends StatelessWidget {
-  const EndGameMessage({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (BuildContext context, GameState gameState) {
-        final Game currentGame = gameState.currentGame;
-
-        String decorationImageAssetName = '';
-        if (currentGame.gameWon) {
-          decorationImageAssetName = 'assets/icons/game_win.png';
-        } else {
-          decorationImageAssetName = 'assets/icons/placeholder.png';
-        }
-
-        final Image decorationImage = Image(
-          image: AssetImage(decorationImageAssetName),
-          fit: BoxFit.fill,
-        );
-
-        return Container(
-          margin: const EdgeInsets.all(2),
-          padding: const EdgeInsets.all(2),
-          child: Table(
-            defaultColumnWidth: const IntrinsicColumnWidth(),
-            children: [
-              TableRow(
-                children: [
-                  Column(children: [decorationImage]),
-                  TextButton(
-                    child: const Image(
-                      image: AssetImage('assets/icons/button_back.png'),
-                      fit: BoxFit.fill,
-                    ),
-                    onPressed: () {
-                      final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-                      gameCubit.quitGame();
-                    },
-                  ),
-                  Column(children: [decorationImage]),
-                ],
-              ),
-            ],
-          ),
-        );
-      },
-    );
-  }
-}
diff --git a/lib/ui/widgets/game/tile_widget.dart b/lib/ui/widgets/game/tile_widget.dart
index 7d71df58bb998882634777b00081a0ce99d0be6a..ee6eb80752aa91217ef426e77b6e6a1fceda74b8 100644
--- a/lib/ui/widgets/game/tile_widget.dart
+++ b/lib/ui/widgets/game/tile_widget.dart
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:solitaire/cubit/game_cubit.dart';
-import 'package:solitaire/models/cell.dart';
-import 'package:solitaire/models/game.dart';
+import 'package:solitaire/models/game/cell.dart';
+import 'package:solitaire/models/game/game.dart';
 
 class TileWidget extends StatelessWidget {
   const TileWidget({
@@ -21,12 +21,10 @@ class TileWidget extends StatelessWidget {
       builder: (BuildContext context, GameState gameState) {
         final Game currentGame = gameState.currentGame;
 
-        final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-
         if (tile.hasHole) {
           return render(
             currentGame: currentGame,
-            gameCubit: gameCubit,
+            gameCubit: BlocProvider.of<GameCubit>(context),
           );
         } else {
           return Image(
diff --git a/lib/ui/widgets/global_app_bar.dart b/lib/ui/widgets/global_app_bar.dart
index 82121035102232012623d4532250a5c551412535..35439421d4723df7b1391ea20ee4f66745ab0128 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:solitaire/config/menu.dart';
 import 'package:solitaire/cubit/game_cubit.dart';
 import 'package:solitaire/cubit/nav_cubit.dart';
-import 'package:solitaire/models/game.dart';
-import 'package:solitaire/ui/widgets/helpers/app_title.dart';
+import 'package:solitaire/models/game/game.dart';
+import 'package:solitaire/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 b5c5be05f6636cf488dcdb5bbc4d6f049b98de11..0000000000000000000000000000000000000000
--- 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 7cbbb2030419047b3dcf093a2195a498bd8e8ce9..0000000000000000000000000000000000000000
--- 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/lib/utils/color_extensions.dart b/lib/utils/color_extensions.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4e55e338f0d3ed98b233d1ef887b7b3e17e29d97
--- /dev/null
+++ b/lib/utils/color_extensions.dart
@@ -0,0 +1,33 @@
+import 'dart:ui';
+
+extension ColorExtension on Color {
+  Color darken([int percent = 40]) {
+    assert(1 <= percent && percent <= 100);
+    final value = 1 - percent / 100;
+    return Color.fromARGB(
+      alpha,
+      (red * value).round(),
+      (green * value).round(),
+      (blue * value).round(),
+    );
+  }
+
+  Color lighten([int percent = 40]) {
+    assert(1 <= percent && percent <= 100);
+    final value = percent / 100;
+    return Color.fromARGB(
+      alpha,
+      (red + ((255 - red) * value)).round(),
+      (green + ((255 - green) * value)).round(),
+      (blue + ((255 - blue) * value)).round(),
+    );
+  }
+
+  Color avg(Color other) {
+    final red = (this.red + other.red) ~/ 2;
+    final green = (this.green + other.green) ~/ 2;
+    final blue = (this.blue + other.blue) ~/ 2;
+    final alpha = (this.alpha + other.alpha) ~/ 2;
+    return Color.fromARGB(alpha, red, green, blue);
+  }
+}
diff --git a/pubspec.lock b/pubspec.lock
index bdba0ef12aaa5e28404023f4cff3d604ec53b942..e0ab96ebb656b1260018d45af586d9ec14ba4a7e 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 5c638793da858ad6a393a3f36a889d1a87ab3897..4068df449b5b92c410cfc80f0b9976470d3d5625 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Solitaire Game
 
 publish_to: "none"
 
-version: 0.0.18+18
+version: 0.1.0+19
 
 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,14 +22,17 @@ 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/skins/
+    - assets/ui/
     - assets/translations/
 
   fonts:
@@ -42,3 +46,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 27dbe2647fe4e6d562fbd99451716d1b7d448570..6d67b8f4f9eca701d1aed7331ef41dfb0bd44f20 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 0000000000000000000000000000000000000000..659697a1c043cfe1c7654635cfaec3e4a0ff8a1a
--- /dev/null
+++ b/resources/build_resources.sh
@@ -0,0 +1,7 @@
+#! /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
+
diff --git a/icons/build_game_icons.sh b/resources/ui/build_ui_resources.sh
similarity index 54%
rename from icons/build_game_icons.sh
rename to resources/ui/build_ui_resources.sh
index 2191261bef769712d228d7a08e5dc97a727ee484..4f365ede7d83140ce6309a3083580f2662b30990 100755
--- a/icons/build_game_icons.sh
+++ b/resources/ui/build_ui_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}")")"
 ASSETS_DIR="${BASE_DIR}/assets"
 
 OPTIPNG_OPTIONS="-preserve -quiet -o7"
@@ -14,25 +14,23 @@ ICON_SIZE=192
 
 #######################################################
 
-# Game images
-AVAILABLE_GAME_IMAGES="
-  button_back
-  button_start
-  game_win
-  placeholder
-"
-
-# Skins
-AVAILABLE_SKINS="
-  default
-"
-
-# Images per skin
-SKIN_IMAGES="
-  board
-  hole
-  peg
-"
+# 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
 
 #######################################################
 
@@ -54,7 +52,7 @@ function optimize_svg() {
 }
 
 # build icons
-function build_icon() {
+function build_image() {
   SOURCE="$1"
   TARGET="$2"
 
@@ -67,43 +65,46 @@ function build_icon() {
 
   optimize_svg "${SOURCE}"
 
+  mkdir -p "$(dirname "${TARGET}")"
+
   inkscape \
       --export-width=${ICON_SIZE} \
       --export-height=${ICON_SIZE} \
       --export-filename=${TARGET} \
-      ${SOURCE}
+      "${SOURCE}"
 
-  optipng ${OPTIPNG_OPTIONS} ${TARGET}
+  optipng ${OPTIPNG_OPTIONS} "${TARGET}"
 }
 
-function build_icon_for_skin() {
+function build_image_for_skin() {
   SKIN_CODE="$1"
 
   # skin images
   for SKIN_IMAGE in ${SKIN_IMAGES}
   do
-    build_icon ${CURRENT_DIR}/skins/${SKIN_CODE}/${SKIN_IMAGE}.svg ${ASSETS_DIR}/skins/${SKIN_CODE}_${SKIN_IMAGE}.png
+    build_image ${CURRENT_DIR}/skins/${SKIN_CODE}/${SKIN_IMAGE}.svg ${ASSETS_DIR}/skins/${SKIN_CODE}_${SKIN_IMAGE}.png
   done
 }
 
 #######################################################
 
-# Create output folders
-mkdir -p ${ASSETS_DIR}/icons
-mkdir -p ${ASSETS_DIR}/skins
-
 # Delete existing generated images
-find ${ASSETS_DIR}/icons -type f -name "*.png" -delete
-find ${ASSETS_DIR}/skins -type f -name "*.png" -delete
+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_icon ${CURRENT_DIR}/${GAME_IMAGE}.svg ${ASSETS_DIR}/icons/${GAME_IMAGE}.png
+  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_icon_for_skin "${SKIN}"
+  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 0000000000000000000000000000000000000000..ac7eefef476f761903fe781b8c86d0c94323550a
--- /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 0000000000000000000000000000000000000000..6ad8b64202d0e70f898c16c520e756fe8a934add
--- /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_fail.svg b/resources/ui/images/game_fail.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2922fd7adc2bd2e813836c728f095376c73d4143
--- /dev/null
+++ b/resources/ui/images/game_fail.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="#d11717" stroke="#fff" stroke-width=".238"/><path d="m71.624 59.304c3.5089 3.5089 3.5089 9.0561 0 12.565-1.6976 1.6976-3.9623 2.6034-6.2261 2.6034s-4.5275-0.90569-6.2261-2.6034l-12.452-12.452-12.452 12.452c-1.6976 1.6976-3.9623 2.6034-6.2261 2.6034s-4.5275-0.90569-6.2261-2.6034c-3.5089-3.5089-3.5089-9.0561 0-12.565l12.452-12.452-12.452-12.452c-3.5089-3.5089-3.5089-9.0561 0-12.565s9.0561-3.5089 12.565 0l12.452 12.452 12.452-12.452c3.5089-3.5089 9.0561-3.5089 12.565 0s3.5089 9.0561 0 12.565l-12.452 12.452z" fill="#e7e7e7" stroke-width=".20213"/></svg>
diff --git a/icons/game_win.svg b/resources/ui/images/game_win.svg
similarity index 100%
rename from icons/game_win.svg
rename to resources/ui/images/game_win.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
diff --git a/icons/skins/default/board.svg b/resources/ui/skins/default/board.svg
similarity index 100%
rename from icons/skins/default/board.svg
rename to resources/ui/skins/default/board.svg
diff --git a/icons/skins/default/hole.svg b/resources/ui/skins/default/hole.svg
similarity index 100%
rename from icons/skins/default/hole.svg
rename to resources/ui/skins/default/hole.svg
diff --git a/icons/skins/default/peg.svg b/resources/ui/skins/default/peg.svg
similarity index 100%
rename from icons/skins/default/peg.svg
rename to resources/ui/skins/default/peg.svg