From db163e64312e2c07374fa7058832ecc25ede4bc1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Sat, 11 May 2024 01:27:40 +0200
Subject: [PATCH] Improve game architecture

---
 android/app/build.gradle                      |   2 +-
 android/gradle.properties                     |   4 +-
 assets/icons/button_delete_saved_game.png     | Bin 5813 -> 0 bytes
 assets/icons/button_resume_game.png           | Bin 3659 -> 0 bytes
 assets/icons/game_fail.png                    | Bin 3647 -> 0 bytes
 assets/icons/layout_diamond.png               | Bin 8682 -> 0 bytes
 assets/icons/layout_english.png               | Bin 8028 -> 0 bytes
 assets/icons/layout_french.png                | Bin 8964 -> 0 bytes
 assets/icons/layout_german.png                | Bin 4358 -> 0 bytes
 assets/icons/skin_default.png                 | Bin 209 -> 0 bytes
 assets/translations/en.json                   |   2 -
 assets/translations/fr.json                   |   2 -
 .../metadata/android/en-US/changelogs/18.txt  |   1 +
 .../metadata/android/fr-FR/changelogs/18.txt  |   1 +
 icons/build_game_icons.sh                     |  30 ---
 icons/button_delete_saved_game.svg            |   2 -
 icons/button_resume_game.svg                  |   2 -
 icons/game_fail.svg                           |   2 -
 icons/layout_diamond.svg                      |   2 -
 icons/layout_english.svg                      |   2 -
 icons/layout_french.svg                       |   2 -
 icons/layout_german.svg                       |   2 -
 icons/skin_default.svg                        |   2 -
 lib/config/default_game_settings.dart         |  33 +++
 lib/config/default_global_settings.dart       |  27 ++
 lib/config/menu.dart                          |  63 ++---
 lib/cubit/game_cubit.dart                     | 127 ++++++++++
 lib/cubit/game_state.dart                     |  19 ++
 .../{bottom_nav_cubit.dart => nav_cubit.dart} |  22 +-
 lib/cubit/settings_game_cubit.dart            |  64 +++++
 lib/cubit/settings_game_state.dart            |  19 ++
 lib/cubit/settings_global_cubit.dart          |  60 +++++
 lib/cubit/settings_global_state.dart          |  19 ++
 lib/data/game_data.dart                       |  44 ++++
 lib/entities/tile.dart                        |  82 ------
 lib/main.dart                                 |  48 ++--
 lib/models/board.dart                         | 169 +++++++++++++
 lib/models/cell.dart                          |  41 +++
 lib/models/cell_location.dart                 |  34 +++
 lib/models/game.dart                          | 142 +++++++++++
 lib/models/settings_game.dart                 |  41 +++
 lib/models/settings_global.dart               |  41 +++
 lib/models/types.dart                         |   0
 lib/provider/data.dart                        | 239 ------------------
 lib/ui/layout/game.dart                       |  36 ---
 lib/ui/layout/parameters.dart                 | 129 ----------
 lib/ui/layout/tileset.dart                    |  42 ---
 lib/ui/painters/parameter_painter.dart        | 190 ++++++++++++++
 lib/ui/screens/game_page.dart                 |  85 -------
 .../{about_page.dart => page_about.dart}      |   6 +-
 lib/ui/screens/page_game.dart                 |  19 ++
 ...{settings_page.dart => page_settings.dart} |   6 +-
 lib/ui/skeleton.dart                          |  37 +--
 lib/ui/widgets/app_bar.dart                   |  37 ---
 lib/ui/widgets/bottom_nav_bar.dart            |  36 ---
 lib/ui/widgets/button_game_start_new.dart     |  34 +++
 lib/ui/widgets/game/game_widget.dart          |  38 +++
 lib/ui/widgets/game/indicator_top.dart        |  62 ++---
 lib/ui/widgets/game/message_game_end.dart     |  68 +++--
 lib/ui/widgets/game/tile_widget.dart          | 135 ++++++++++
 lib/ui/widgets/game/tileset.dart              |  45 ++++
 lib/ui/widgets/global_app_bar.dart            |  84 ++++++
 .../app_header.dart}                          |   5 +-
 lib/ui/widgets/helpers/app_title.dart         |  17 ++
 lib/ui/widgets/home/button_game_restart.dart  |  21 --
 lib/ui/widgets/home/button_game_resume.dart   |  42 ---
 .../widgets/home/button_game_start_new.dart   |  38 ---
 lib/ui/widgets/parameters.dart                | 115 +++++++++
 lib/utils/board_utils.dart                    | 120 ---------
 lib/utils/game_utils.dart                     | 180 -------------
 pubspec.lock                                  |  92 +++----
 pubspec.yaml                                  |  16 +-
 72 files changed, 1780 insertions(+), 1347 deletions(-)
 delete mode 100644 assets/icons/button_delete_saved_game.png
 delete mode 100644 assets/icons/button_resume_game.png
 delete mode 100644 assets/icons/game_fail.png
 delete mode 100644 assets/icons/layout_diamond.png
 delete mode 100644 assets/icons/layout_english.png
 delete mode 100644 assets/icons/layout_french.png
 delete mode 100644 assets/icons/layout_german.png
 delete mode 100644 assets/icons/skin_default.png
 create mode 100644 fastlane/metadata/android/en-US/changelogs/18.txt
 create mode 100644 fastlane/metadata/android/fr-FR/changelogs/18.txt
 delete mode 100644 icons/button_delete_saved_game.svg
 delete mode 100644 icons/button_resume_game.svg
 delete mode 100644 icons/game_fail.svg
 delete mode 100644 icons/layout_diamond.svg
 delete mode 100644 icons/layout_english.svg
 delete mode 100644 icons/layout_french.svg
 delete mode 100644 icons/layout_german.svg
 delete mode 100644 icons/skin_default.svg
 create mode 100644 lib/config/default_game_settings.dart
 create mode 100644 lib/config/default_global_settings.dart
 create mode 100644 lib/cubit/game_cubit.dart
 create mode 100644 lib/cubit/game_state.dart
 rename lib/cubit/{bottom_nav_cubit.dart => nav_cubit.dart} (51%)
 create mode 100644 lib/cubit/settings_game_cubit.dart
 create mode 100644 lib/cubit/settings_game_state.dart
 create mode 100644 lib/cubit/settings_global_cubit.dart
 create mode 100644 lib/cubit/settings_global_state.dart
 create mode 100644 lib/data/game_data.dart
 delete mode 100644 lib/entities/tile.dart
 create mode 100644 lib/models/board.dart
 create mode 100644 lib/models/cell.dart
 create mode 100644 lib/models/cell_location.dart
 create mode 100644 lib/models/game.dart
 create mode 100644 lib/models/settings_game.dart
 create mode 100644 lib/models/settings_global.dart
 create mode 100644 lib/models/types.dart
 delete mode 100644 lib/provider/data.dart
 delete mode 100644 lib/ui/layout/game.dart
 delete mode 100644 lib/ui/layout/parameters.dart
 delete mode 100644 lib/ui/layout/tileset.dart
 create mode 100644 lib/ui/painters/parameter_painter.dart
 delete mode 100644 lib/ui/screens/game_page.dart
 rename lib/ui/screens/{about_page.dart => page_about.dart} (89%)
 create mode 100644 lib/ui/screens/page_game.dart
 rename lib/ui/screens/{settings_page.dart => page_settings.dart} (80%)
 delete mode 100644 lib/ui/widgets/app_bar.dart
 delete mode 100644 lib/ui/widgets/bottom_nav_bar.dart
 create mode 100644 lib/ui/widgets/button_game_start_new.dart
 create mode 100644 lib/ui/widgets/game/game_widget.dart
 create mode 100644 lib/ui/widgets/game/tile_widget.dart
 create mode 100644 lib/ui/widgets/game/tileset.dart
 create mode 100644 lib/ui/widgets/global_app_bar.dart
 rename lib/ui/widgets/{header_app.dart => helpers/app_header.dart} (77%)
 create mode 100644 lib/ui/widgets/helpers/app_title.dart
 delete mode 100644 lib/ui/widgets/home/button_game_restart.dart
 delete mode 100644 lib/ui/widgets/home/button_game_resume.dart
 delete mode 100644 lib/ui/widgets/home/button_game_start_new.dart
 create mode 100644 lib/ui/widgets/parameters.dart
 delete mode 100644 lib/utils/board_utils.dart
 delete mode 100644 lib/utils/game_utils.dart

diff --git a/android/app/build.gradle b/android/app/build.gradle
index 9e2643e..c3c8f66 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -37,7 +37,7 @@ if (keystorePropertiesFile.exists()) {
 }
 
 android {
-    compileSdkVersion 33
+    compileSdkVersion 34
     namespace "org.benoitharrault.solitaire"
 
     defaultConfig {
diff --git a/android/gradle.properties b/android/gradle.properties
index cd2d833..30298b3 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.17
-app.versionCode=17
+app.versionName=0.0.18
+app.versionCode=18
diff --git a/assets/icons/button_delete_saved_game.png b/assets/icons/button_delete_saved_game.png
deleted file mode 100644
index 5e4f217689b11e444b7163557d7e5d68f3bbfe7d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5813
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

diff --git a/assets/icons/button_resume_game.png b/assets/icons/button_resume_game.png
deleted file mode 100644
index b2ea0a02d05e42377eb551a4b51428b511a32f5d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3659
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

diff --git a/assets/icons/game_fail.png b/assets/icons/game_fail.png
deleted file mode 100644
index 93f2801f9d6bb2ce508e1293cd64d6ff2e9970ec..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3647
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
a*}uy$dF>W!zRtkFz~JfX=d#Wzp$P!#%#zLk

diff --git a/assets/icons/layout_diamond.png b/assets/icons/layout_diamond.png
deleted file mode 100644
index d20c4ea546b070361e0d0d3aeb6682bca69273a6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 8682
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

diff --git a/assets/icons/layout_english.png b/assets/icons/layout_english.png
deleted file mode 100644
index 3ca9c27286c0fc3ec7d3808cd23118965b95892d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 8028
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
W|LvreHnt253=E#GelF{r5}E*;4ztMs

diff --git a/assets/icons/layout_french.png b/assets/icons/layout_french.png
deleted file mode 100644
index 71837c08f529075e14fce4db01f166cf9ac36d6c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 8964
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

diff --git a/assets/icons/layout_german.png b/assets/icons/layout_german.png
deleted file mode 100644
index 37c51ca8fdb173b33d06b23435a806fdb215b9bd..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4358
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

diff --git a/assets/icons/skin_default.png b/assets/icons/skin_default.png
deleted file mode 100644
index fbe9cb151a27e54b848f7cd48e397cd308f51dad..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 209
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE6Ow0@n4Emc|rZ6xta29w(7BetNp8{b<xs?;d
z85kHOOI#yLg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T3kz!zA;0f>vab;j&;9}#^
zku=_ybuWLT*gFOW1~*R^$B>N1x3>&=859Iq4zj0uIP<GH9xjzPy4~Nr_SJQZz}3%s
iZ!zEkADBDbXV=+Uv~<5Jn~-e-Qs(LE=d#Wzp$Py8rZ`0a

diff --git a/assets/translations/en.json b/assets/translations/en.json
index edfb95a..13da5fc 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -1,8 +1,6 @@
 {
   "app_name": "Solitaire",
 
-  "long_press_to_quit": "Long press to quit game...",
-
   "bottom_nav_home": "Game",
   "bottom_nav_settings": "Settings",
   "bottom_nav_about": "About",
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
index a4e231e..0d43876 100644
--- a/assets/translations/fr.json
+++ b/assets/translations/fr.json
@@ -1,8 +1,6 @@
 {
   "app_name": "Solitaire",
 
-  "long_press_to_quit": "Appuyer longtemps pour quitter le jeu...",
-
   "bottom_nav_home": "Jeu",
   "bottom_nav_settings": "Réglages",
   "bottom_nav_about": "Infos",
diff --git a/fastlane/metadata/android/en-US/changelogs/18.txt b/fastlane/metadata/android/en-US/changelogs/18.txt
new file mode 100644
index 0000000..9bb4c4d
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/18.txt
@@ -0,0 +1 @@
+Improve application architecture.
diff --git a/fastlane/metadata/android/fr-FR/changelogs/18.txt b/fastlane/metadata/android/fr-FR/changelogs/18.txt
new file mode 100644
index 0000000..5face79
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/18.txt
@@ -0,0 +1 @@
+Amélioration de l'architecture de l'application.
diff --git a/icons/build_game_icons.sh b/icons/build_game_icons.sh
index 4a9ca31..2191261 100755
--- a/icons/build_game_icons.sh
+++ b/icons/build_game_icons.sh
@@ -18,18 +18,10 @@ ICON_SIZE=192
 AVAILABLE_GAME_IMAGES="
   button_back
   button_start
-  button_resume_game
-  button_delete_saved_game
-  game_fail
   game_win
   placeholder
 "
 
-# Settings images
-AVAILABLES_GAME_SETTINGS="
-  layout:french,german,english,diamond
-"
-
 # Skins
 AVAILABLE_SKINS="
   default
@@ -84,25 +76,9 @@ function build_icon() {
   optipng ${OPTIPNG_OPTIONS} ${TARGET}
 }
 
-function build_settings_icons() {
-  INPUT_STRING="$1"
-
-  SETTING_NAME="$(echo "${INPUT_STRING}" | cut -d":" -f1)"
-  SETTING_VALUES="$(echo "${INPUT_STRING}" | cut -d":" -f2 | tr "," " ")"
-
-  for SETTING_VALUE in ${SETTING_VALUES}
-  do
-    SETTING_CODE="${SETTING_NAME}_${SETTING_VALUE}"
-    build_icon ${CURRENT_DIR}/${SETTING_CODE}.svg ${ASSETS_DIR}/icons/${SETTING_CODE}.png
-  done
-}
-
 function build_icon_for_skin() {
   SKIN_CODE="$1"
 
-  # skin main image
-  build_icon ${CURRENT_DIR}/skin_${SKIN_CODE}.svg ${ASSETS_DIR}/icons/skin_${SKIN_CODE}.png
-
   # skin images
   for SKIN_IMAGE in ${SKIN_IMAGES}
   do
@@ -126,12 +102,6 @@ do
   build_icon ${CURRENT_DIR}/${GAME_IMAGE}.svg ${ASSETS_DIR}/icons/${GAME_IMAGE}.png
 done
 
-# build settings images
-for GAME_SETTING in ${AVAILABLES_GAME_SETTINGS}
-do
-  build_settings_icons "${GAME_SETTING}"
-done
-
 # build skins images
 for SKIN in ${AVAILABLE_SKINS}
 do
diff --git a/icons/button_delete_saved_game.svg b/icons/button_delete_saved_game.svg
deleted file mode 100644
index ac7eefe..0000000
--- a/icons/button_delete_saved_game.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?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/icons/button_resume_game.svg b/icons/button_resume_game.svg
deleted file mode 100644
index 6ad8b64..0000000
--- a/icons/button_resume_game.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?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/game_fail.svg b/icons/game_fail.svg
deleted file mode 100644
index 2922fd7..0000000
--- a/icons/game_fail.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?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/layout_diamond.svg b/icons/layout_diamond.svg
deleted file mode 100644
index 31d08b4..0000000
--- a/icons/layout_diamond.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#6ade70" stroke="#000" stroke-width="2"/><g transform="matrix(.8379 0 0 .8379 -396.44 -4.3017)"><g transform="translate(180 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(228 96)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(228 3.624e-5)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 72)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(228 72)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(228 24)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 24)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 60)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 60)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 60)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(192 48)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(192 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(192 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(204 48)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(204 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(204 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 48)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 48)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 48)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 48)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 36)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(276 36)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 48)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 48)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 48)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 48)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><rect x="528" y="60" width="12" height="12" fill="#babdb6" stroke="#000"/><g transform="translate(240 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 48)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 48)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 48)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(240 12)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g></g></svg>
diff --git a/icons/layout_english.svg b/icons/layout_english.svg
deleted file mode 100644
index c819ca6..0000000
--- a/icons/layout_english.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#6ade70" stroke="#000" stroke-width="2"/><g transform="translate(-363 -3)"><g transform="translate(120 48)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 48)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 48)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(72 36)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(72 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(72 24)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(84 36)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(84 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(84 24)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(156 36)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(156 36)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(156 36)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(156 36)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(156 24)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(156 24)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 36)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 36)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 36)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 36)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><rect x="408" y="48" width="12" height="12" fill="#babdb6" stroke="#000"/><g transform="translate(120 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 36)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 36)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(120 36)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(86.461 -21.272)"><g transform="translate(33.539 21.272)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(33.539 21.272)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g></g></g></svg>
diff --git a/icons/layout_french.svg b/icons/layout_french.svg
deleted file mode 100644
index 1ff5efe..0000000
--- a/icons/layout_french.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#6ade70" stroke="#000" stroke-width="2"/><g transform="translate(-3 -15)"><g transform="translate(-204 72)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-252 72)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-252 24)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-204 24)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 60)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 60)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 60)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-288 48)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-288 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-288 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-276 48)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-276 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-276 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-204 48)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-204 48)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-204 48)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-204 48)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-204 36)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-204 36)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="288" y="24" width="12" height="12" fill="#babdb6" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 48)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 12)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 12)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 12)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 12)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 12)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 12)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-240 12)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><rect x="48" y="48" width="12" height="12" fill="#fff" stroke="#000"/><rect x="48" y="60" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 -100.3 35.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/><g transform="translate(-240 12)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g></g></svg>
diff --git a/icons/layout_german.svg b/icons/layout_german.svg
deleted file mode 100644
index e826669..0000000
--- a/icons/layout_german.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#6ade70" stroke="#000" stroke-width="2"/><g transform="matrix(.84066 0 0 .84066 -95.275 -4.4834)"><g transform="translate(-168 36)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-168 36)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-168 36)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 72)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 3.0518e-5)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-156 36)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-156 36)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-156 36)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-156 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-156 36)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-156 36)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 36)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><rect x="168" y="60" width="12" height="12" fill="#babdb6" stroke="#000"/><g transform="translate(-120 36)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 36)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 36)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 36)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 36)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-120 36)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="276" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="288" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="300" y="24" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -.3088)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="276" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="288" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="300" y="12" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 -12.309)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="276" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 127.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="288" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 139.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g><g transform="translate(-84 36)"><rect x="300" y="36" width="12" height="12" fill="#fff" stroke="#000"/><circle transform="matrix(.5381 0 0 .5381 151.7 11.691)" cx="286.74" cy="56.325" r="7.4335" fill="#c17d11"/></g></g></svg>
diff --git a/icons/skin_default.svg b/icons/skin_default.svg
deleted file mode 100644
index f7344d5..0000000
--- a/icons/skin_default.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><rect x="1" y="1" width="100" height="100" ry="0" fill="#be6ade" stroke="#000" stroke-width="2"/></svg>
diff --git a/lib/config/default_game_settings.dart b/lib/config/default_game_settings.dart
new file mode 100644
index 0000000..6ac27dc
--- /dev/null
+++ b/lib/config/default_game_settings.dart
@@ -0,0 +1,33 @@
+import 'package:solitaire/utils/tools.dart';
+
+class DefaultGameSettings {
+  // available game parameters codes
+  static const String parameterCodeLayout = 'layout';
+  static const List<String> availableParameters = [
+    parameterCodeLayout,
+  ];
+
+  // layout: available values
+  static const String layoutValueFrench = 'french';
+  static const String layoutValueGerman = 'german';
+  static const String layoutValueEnglish = 'english';
+  static const String layoutValueDiamond = 'diamond';
+  static const List<String> allowedLayoutValues = [
+    layoutValueFrench,
+    layoutValueGerman,
+    layoutValueEnglish,
+    layoutValueDiamond,
+  ];
+  // layout: default value
+  static const String defaultLayoutValue = layoutValueEnglish;
+
+  static List<String> getAvailableValues(String parameterCode) {
+    switch (parameterCode) {
+      case parameterCodeLayout:
+        return DefaultGameSettings.allowedLayoutValues;
+    }
+
+    printlog('Did not find any available value for game parameter "$parameterCode".');
+    return [];
+  }
+}
diff --git a/lib/config/default_global_settings.dart b/lib/config/default_global_settings.dart
new file mode 100644
index 0000000..622a8b6
--- /dev/null
+++ b/lib/config/default_global_settings.dart
@@ -0,0 +1,27 @@
+import 'package:solitaire/utils/tools.dart';
+
+class DefaultGlobalSettings {
+  // 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;
+
+  static List<String> getAvailableValues(String parameterCode) {
+    switch (parameterCode) {
+      case parameterCodeSkin:
+        return DefaultGlobalSettings.allowedSkinValues;
+    }
+
+    printlog('Did not find any available value for global parameter "$parameterCode".');
+    return [];
+  }
+}
diff --git a/lib/config/menu.dart b/lib/config/menu.dart
index ca5d227..3d2fcfa 100644
--- a/lib/config/menu.dart
+++ b/lib/config/menu.dart
@@ -1,10 +1,9 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:unicons/unicons.dart';
 
-import 'package:solitaire/ui/screens/about_page.dart';
-import 'package:solitaire/ui/screens/game_page.dart';
-import 'package:solitaire/ui/screens/settings_page.dart';
+import 'package:solitaire/ui/screens/page_about.dart';
+import 'package:solitaire/ui/screens/page_game.dart';
+import 'package:solitaire/ui/screens/page_settings.dart';
 
 class MenuItem {
   final String code;
@@ -19,35 +18,39 @@ class MenuItem {
 }
 
 class Menu {
-  static List<MenuItem> items = [
-    const MenuItem(
-      code: 'bottom_nav_home',
-      icon: Icon(UniconsLine.home),
-      page: GamePage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_settings',
-      icon: Icon(UniconsLine.setting),
-      page: SettingsPage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_about',
-      icon: Icon(UniconsLine.info_circle),
-      page: AboutPage(),
-    ),
-  ];
+  static const indexGame = 0;
+  static const menuItemGame = MenuItem(
+    code: 'bottom_nav_game',
+    icon: Icon(UniconsLine.home),
+    page: PageGame(),
+  );
 
-  static Widget getPageWidget(int pageIndex) {
-    return Menu.items.elementAt(pageIndex).page;
+  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(),
+  );
+
+  static Map<int, MenuItem> items = {
+    indexGame: menuItemGame,
+    indexSettings: menuItemSettings,
+    indexAbout: menuItemAbout,
+  };
+
+  static bool isIndexAllowed(int pageIndex) {
+    return items.keys.contains(pageIndex);
   }
 
-  static List<BottomNavigationBarItem> getMenuItems() {
-    return Menu.items
-        .map((MenuItem item) => BottomNavigationBarItem(
-              icon: item.icon,
-              label: tr(item.code),
-            ))
-        .toList();
+  static Widget getPageWidget(int pageIndex) {
+    return items[pageIndex]?.page ?? menuItemGame.page;
   }
 
   static int itemsCount = Menu.items.length;
diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart
new file mode 100644
index 0000000..aba2472
--- /dev/null
+++ b/lib/cubit/game_cubit.dart
@@ -0,0 +1,127 @@
+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/utils/tools.dart';
+
+part 'game_state.dart';
+
+class GameCubit extends HydratedCubit<GameState> {
+  GameCubit()
+      : super(GameState(
+          currentGame: Game.createNull(),
+        ));
+
+  void updateState(Game game) {
+    emit(GameState(
+      currentGame: game,
+    ));
+  }
+
+  void refresh() {
+    final Game game = Game(
+      gameSettings: state.currentGame.gameSettings,
+      globalSettings: state.currentGame.globalSettings,
+      board: state.currentGame.board,
+      isRunning: state.currentGame.isRunning,
+      isFinished: state.currentGame.isFinished,
+      movesCount: state.currentGame.movesCount,
+      remainingPegsCount: state.currentGame.remainingPegsCount,
+      allowedMovesCount: state.currentGame.allowedMovesCount,
+    );
+    // game.dump();
+
+    updateState(game);
+  }
+
+  void startNewGame({
+    required GameSettings gameSettings,
+    required GlobalSettings globalSettings,
+  }) {
+    Game newGame = Game.createNew(
+      gameSettings: gameSettings,
+      globalSettings: globalSettings,
+    );
+
+    newGame.dump();
+
+    updateState(newGame);
+
+    updateRemainingPegsCount(newGame.countRemainingPegs());
+    updateAllowedMovesCount(newGame.countAllowedMoves());
+
+    refresh();
+  }
+
+  void quitGame() {
+    state.currentGame.isRunning = false;
+    refresh();
+  }
+
+  void updatePegValue(CellLocation location, bool hasPeg) {
+    state.currentGame.board.cells[location.row][location.col].hasPeg = hasPeg;
+    refresh();
+  }
+
+  void incrementMovesCount() {
+    state.currentGame.movesCount++;
+    refresh();
+  }
+
+  void updateRemainingPegsCount(int count) {
+    state.currentGame.remainingPegsCount = count;
+    refresh();
+  }
+
+  void updateAllowedMovesCount(int count) {
+    state.currentGame.allowedMovesCount = count;
+    if (count == 0) {
+      state.currentGame.isFinished = true;
+    }
+
+    refresh();
+  }
+
+  void move({
+    required Game currentGame,
+    required List<int> source,
+    required List<int> target,
+  }) {
+    printlog('Move from $source to $target');
+    final int sourceCol = source[0];
+    final int sourceRow = source[1];
+    final int targetCol = target[0];
+    final int targetRow = target[1];
+
+    final int middleRow = (sourceRow + ((targetRow - sourceRow) / 2)).round();
+    final int middleCol = (sourceCol + ((targetCol - sourceCol) / 2)).round();
+
+    updatePegValue(CellLocation.go(sourceRow, sourceCol), false);
+    updatePegValue(CellLocation.go(targetRow, targetCol), true);
+    updatePegValue(CellLocation.go(middleRow, middleCol), false);
+
+    incrementMovesCount();
+    updateRemainingPegsCount(currentGame.countRemainingPegs());
+    updateAllowedMovesCount(currentGame.countAllowedMoves());
+  }
+
+  @override
+  GameState? fromJson(Map<String, dynamic> json) {
+    Game currentGame = json['currentGame'] as Game;
+
+    return GameState(
+      currentGame: currentGame,
+    );
+  }
+
+  @override
+  Map<String, dynamic>? toJson(GameState state) {
+    return <String, dynamic>{
+      'currentGame': state.currentGame.toJson(),
+    };
+  }
+}
diff --git a/lib/cubit/game_state.dart b/lib/cubit/game_state.dart
new file mode 100644
index 0000000..3fd161a
--- /dev/null
+++ b/lib/cubit/game_state.dart
@@ -0,0 +1,19 @@
+part of 'game_cubit.dart';
+
+@immutable
+class GameState extends Equatable {
+  const GameState({
+    required this.currentGame,
+  });
+
+  final Game currentGame;
+
+  @override
+  List<dynamic> get props => <dynamic>[
+        currentGame,
+      ];
+
+  Map<String, dynamic> get values => <String, dynamic>{
+        'currentGame': currentGame,
+      };
+}
diff --git a/lib/cubit/bottom_nav_cubit.dart b/lib/cubit/nav_cubit.dart
similarity index 51%
rename from lib/cubit/bottom_nav_cubit.dart
rename to lib/cubit/nav_cubit.dart
index 8f04dff..9d4541c 100644
--- a/lib/cubit/bottom_nav_cubit.dart
+++ b/lib/cubit/nav_cubit.dart
@@ -2,26 +2,32 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 import 'package:solitaire/config/menu.dart';
 
-class BottomNavCubit extends HydratedCubit<int> {
-  BottomNavCubit() : super(0);
+class NavCubit extends HydratedCubit<int> {
+  NavCubit() : super(0);
 
   void updateIndex(int index) {
-    if (isIndexAllowed(index)) {
+    if (Menu.isIndexAllowed(index)) {
       emit(index);
     } else {
-      goToHomePage();
+      goToGamePage();
     }
   }
 
-  bool isIndexAllowed(int index) {
-    return (index >= 0) && (index < Menu.itemsCount);
+  void goToGamePage() {
+    emit(Menu.indexGame);
   }
 
-  void goToHomePage() => emit(0);
+  void goToSettingsPage() {
+    emit(Menu.indexSettings);
+  }
+
+  void goToAboutPage() {
+    emit(Menu.indexAbout);
+  }
 
   @override
   int fromJson(Map<String, dynamic> json) {
-    return 0;
+    return Menu.indexGame;
   }
 
   @override
diff --git a/lib/cubit/settings_game_cubit.dart b/lib/cubit/settings_game_cubit.dart
new file mode 100644
index 0000000..7399314
--- /dev/null
+++ b/lib/cubit/settings_game_cubit.dart
@@ -0,0 +1,64 @@
+import 'package:equatable/equatable.dart';
+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';
+
+part 'settings_game_state.dart';
+
+class GameSettingsCubit extends HydratedCubit<GameSettingsState> {
+  GameSettingsCubit() : super(GameSettingsState(settings: GameSettings.createDefault()));
+
+  void setValues({
+    String? layout,
+  }) {
+    emit(
+      GameSettingsState(
+        settings: GameSettings(
+          layout: layout ?? state.settings.layout,
+        ),
+      ),
+    );
+  }
+
+  String getParameterValue(String code) {
+    switch (code) {
+      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
+        ? value
+        : getParameterValue(DefaultGameSettings.parameterCodeLayout);
+
+    setValues(
+      layout: layout,
+    );
+  }
+
+  @override
+  GameSettingsState? fromJson(Map<String, dynamic> json) {
+    String layout = json[DefaultGameSettings.parameterCodeLayout] as String;
+
+    return GameSettingsState(
+      settings: GameSettings(
+        layout: layout,
+      ),
+    );
+  }
+
+  @override
+  Map<String, dynamic>? toJson(GameSettingsState state) {
+    return <String, dynamic>{
+      DefaultGameSettings.parameterCodeLayout: state.settings.layout,
+    };
+  }
+}
diff --git a/lib/cubit/settings_game_state.dart b/lib/cubit/settings_game_state.dart
new file mode 100644
index 0000000..b773dc6
--- /dev/null
+++ b/lib/cubit/settings_game_state.dart
@@ -0,0 +1,19 @@
+part of 'settings_game_cubit.dart';
+
+@immutable
+class GameSettingsState extends Equatable {
+  const GameSettingsState({
+    required this.settings,
+  });
+
+  final GameSettings settings;
+
+  @override
+  List<dynamic> get props => <dynamic>[
+        settings,
+      ];
+
+  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
new file mode 100644
index 0000000..274c113
--- /dev/null
+++ b/lib/cubit/settings_global_cubit.dart
@@ -0,0 +1,60 @@
+import 'package:equatable/equatable.dart';
+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';
+
+part 'settings_global_state.dart';
+
+class GlobalSettingsCubit extends HydratedCubit<GlobalSettingsState> {
+  GlobalSettingsCubit() : super(GlobalSettingsState(settings: GlobalSettings.createDefault()));
+
+  void setValues({
+    String? skin,
+  }) {
+    emit(
+      GlobalSettingsState(
+        settings: GlobalSettings(
+          skin: skin ?? state.settings.skin,
+        ),
+      ),
+    );
+  }
+
+  String getParameterValue(String code) {
+    switch (code) {
+      case DefaultGlobalSettings.parameterCodeSkin:
+        return GlobalSettings.getSkinValueFromUnsafe(state.settings.skin);
+    }
+    return '';
+  }
+
+  void setParameterValue(String code, String value) {
+    final String skin = (code == DefaultGlobalSettings.parameterCodeSkin)
+        ? value
+        : getParameterValue(DefaultGlobalSettings.parameterCodeSkin);
+
+    setValues(
+      skin: skin,
+    );
+  }
+
+  @override
+  GlobalSettingsState? fromJson(Map<String, dynamic> json) {
+    final String skin = json[DefaultGlobalSettings.parameterCodeSkin] as String;
+
+    return GlobalSettingsState(
+      settings: GlobalSettings(
+        skin: skin,
+      ),
+    );
+  }
+
+  @override
+  Map<String, dynamic>? toJson(GlobalSettingsState state) {
+    return <String, dynamic>{
+      DefaultGlobalSettings.parameterCodeSkin: state.settings.skin,
+    };
+  }
+}
diff --git a/lib/cubit/settings_global_state.dart b/lib/cubit/settings_global_state.dart
new file mode 100644
index 0000000..4e4fbdf
--- /dev/null
+++ b/lib/cubit/settings_global_state.dart
@@ -0,0 +1,19 @@
+part of 'settings_global_cubit.dart';
+
+@immutable
+class GlobalSettingsState extends Equatable {
+  const GlobalSettingsState({
+    required this.settings,
+  });
+
+  final GlobalSettings settings;
+
+  @override
+  List<dynamic> get props => <dynamic>[
+        settings,
+      ];
+
+  Map<String, dynamic> get values => <String, dynamic>{
+        'settings': settings,
+      };
+}
diff --git a/lib/data/game_data.dart b/lib/data/game_data.dart
new file mode 100644
index 0000000..711256b
--- /dev/null
+++ b/lib/data/game_data.dart
@@ -0,0 +1,44 @@
+class GameData {
+  static const Map<String, List<String>> templates = {
+    'french': [
+      '  ooo  ',
+      ' ooooo ',
+      'ooo·ooo',
+      'ooooooo',
+      'ooooooo',
+      ' ooooo ',
+      '  ooo  ',
+    ],
+    'german': [
+      '   ooo   ',
+      '   ooo   ',
+      '   ooo   ',
+      'ooooooooo',
+      'oooo·oooo',
+      'ooooooooo',
+      '   ooo   ',
+      '   ooo   ',
+      '   ooo   ',
+    ],
+    'english': [
+      '  ooo  ',
+      '  ooo  ',
+      'ooooooo',
+      'ooo·ooo',
+      'ooooooo',
+      '  ooo  ',
+      '  ooo  ',
+    ],
+    'diamond': [
+      '    o    ',
+      '   ooo   ',
+      '  ooooo  ',
+      ' ooooooo ',
+      'oooo·oooo',
+      ' ooooooo ',
+      '  ooooo  ',
+      '   ooo   ',
+      '    o    ',
+    ]
+  };
+}
diff --git a/lib/entities/tile.dart b/lib/entities/tile.dart
deleted file mode 100644
index 5f88b97..0000000
--- a/lib/entities/tile.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/utils/game_utils.dart';
-
-class Tile {
-  int currentRow;
-  int currentCol;
-  bool hasPeg;
-
-  Tile(
-    this.currentRow,
-    this.currentCol,
-    this.hasPeg,
-  );
-
-  Widget render(Data myProvider) {
-    List<Widget> stack = [
-      hole(myProvider),
-    ];
-
-    if (hasPeg) {
-      stack.add(draggable(myProvider));
-    }
-
-    return Stack(
-      alignment: Alignment.center,
-      children: stack,
-    );
-  }
-
-  Widget hole(Data myProvider) {
-    String image = 'assets/skins/${myProvider.parameterSkin}_hole.png';
-
-    return DragTarget<List<int>>(
-      builder: (
-        BuildContext context,
-        List<dynamic> accepted,
-        List<dynamic> rejected,
-      ) {
-        return Image(
-          image: AssetImage(image),
-          width: myProvider.tileSize,
-          height: myProvider.tileSize,
-          fit: BoxFit.fill,
-        );
-      },
-      onAcceptWithDetails: (DragTargetDetails<List<int>> source) {
-        List<int> target = [currentCol, currentRow];
-        // printlog('(drag) Pick from ' + source.toString() + ' and drop on ' + target.toString());
-        if (GameUtils.isMoveAllowed(myProvider, source.data, target)) {
-          GameUtils.move(myProvider, source.data, target);
-        }
-      },
-    );
-  }
-
-  Widget draggable(Data myProvider) {
-    return Draggable<List<int>>(
-      data: [currentCol, currentRow],
-
-      // Widget when draggable is being dragged
-      feedback: peg(myProvider),
-
-      // Widget to display on original place when being dragged
-      childWhenDragging: Container(),
-
-      // Widget when draggable is stationary
-      child: peg(myProvider),
-    );
-  }
-
-  Widget peg(Data myProvider) {
-    String image = 'assets/skins/${myProvider.parameterSkin}_peg.png';
-
-    return Image(
-      image: AssetImage(image),
-      width: myProvider.tileSize,
-      height: myProvider.tileSize,
-      fit: BoxFit.fill,
-    );
-  }
-}
diff --git a/lib/main.dart b/lib/main.dart
index e84151f..d507c2d 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -6,17 +6,17 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:hive/hive.dart';
 import 'package:hydrated_bloc/hydrated_bloc.dart';
 import 'package:path_provider/path_provider.dart';
-import 'package:provider/provider.dart';
-import 'package:overlay_support/overlay_support.dart';
 
 import 'package:solitaire/config/theme.dart';
-import 'package:solitaire/cubit/bottom_nav_cubit.dart';
+import 'package:solitaire/cubit/game_cubit.dart';
+import 'package:solitaire/cubit/nav_cubit.dart';
+import 'package:solitaire/cubit/settings_game_cubit.dart';
+import 'package:solitaire/cubit/settings_global_cubit.dart';
 import 'package:solitaire/cubit/theme_cubit.dart';
-import 'package:solitaire/provider/data.dart';
 import 'package:solitaire/ui/skeleton.dart';
 
 void main() async {
-  /// Initialize packages
+  // Initialize packages
   WidgetsFlutterBinding.ensureInitialized();
   await EasyLocalization.ensureInitialized();
   final Directory tmpDir = await getTemporaryDirectory();
@@ -46,34 +46,28 @@ class MyApp extends StatelessWidget {
   Widget build(BuildContext context) {
     return MultiBlocProvider(
       providers: [
-        BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
+        BlocProvider<NavCubit>(create: (context) => NavCubit()),
         BlocProvider<ThemeCubit>(create: (context) => ThemeCubit()),
+        BlocProvider<GameCubit>(create: (context) => GameCubit()),
+        BlocProvider<GlobalSettingsCubit>(create: (context) => GlobalSettingsCubit()),
+        BlocProvider<GameSettingsCubit>(create: (context) => GameSettingsCubit()),
       ],
       child: BlocBuilder<ThemeCubit, ThemeModeState>(
         builder: (BuildContext context, ThemeModeState state) {
-          return ChangeNotifierProvider(
-            create: (BuildContext context) => Data(),
-            child: Consumer<Data>(
-              builder: (context, data, child) {
-                return OverlaySupport(
-                  child: MaterialApp(
-                    title: 'Solitaire',
-                    home: const SkeletonScreen(),
+          return MaterialApp(
+            title: 'Solitaire',
+            home: const SkeletonScreen(),
 
-                    // Theme stuff
-                    theme: lightTheme,
-                    darkTheme: darkTheme,
-                    themeMode: state.themeMode,
+            // Theme stuff
+            theme: lightTheme,
+            darkTheme: darkTheme,
+            themeMode: state.themeMode,
 
-                    // Localization stuff
-                    localizationsDelegates: context.localizationDelegates,
-                    supportedLocales: context.supportedLocales,
-                    locale: context.locale,
-                    debugShowCheckedModeBanner: false,
-                  ),
-                );
-              },
-            ),
+            // Localization stuff
+            localizationsDelegates: context.localizationDelegates,
+            supportedLocales: context.supportedLocales,
+            locale: context.locale,
+            debugShowCheckedModeBanner: false,
           );
         },
       ),
diff --git a/lib/models/board.dart b/lib/models/board.dart
new file mode 100644
index 0000000..eb1ce73
--- /dev/null
+++ b/lib/models/board.dart
@@ -0,0 +1,169 @@
+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/utils/tools.dart';
+
+typedef BoardCells = List<List<Cell>>;
+
+class Board {
+  Board({
+    required this.cells,
+  });
+
+  BoardCells cells = const [];
+
+  factory Board.createEmpty() {
+    return Board(
+      cells: [],
+    );
+  }
+
+  factory Board.createNew({
+    required GameSettings gameSettings,
+  }) {
+    final List<String>? template = GameData.templates[gameSettings.layout];
+
+    final BoardCells grid = [];
+
+    int row = 0;
+    template?.forEach((String line) {
+      final List<Cell> gridLine = [];
+      int col = 0;
+      line.split("").forEach((String tileCode) {
+        gridLine.add(tileCode == ' '
+            ? Cell.none
+            : Cell(
+                location: CellLocation.go(row, col),
+                hasHole: true,
+                hasPeg: (tileCode == 'o'),
+              ));
+        col++;
+      });
+      row++;
+      grid.add(gridLine);
+    });
+
+    return Board(
+      cells: grid,
+    );
+  }
+
+  int get boardSize => cells.length;
+
+  Cell get(CellLocation location) {
+    if (location.row < cells.length) {
+      if (location.col < cells[location.row].length) {
+        return cells[location.row][location.col];
+      }
+    }
+
+    return Cell.none;
+  }
+
+  void set(CellLocation location, Cell cell) {
+    cells[location.row][location.col] = cell;
+  }
+
+  bool isMoveAllowed({
+    required List<int> source,
+    required List<int> target,
+  }) {
+    // printlog('(test) Pick from ' + source.toString() + ' and drop on ' + target.toString());
+    final int sourceCol = source[0];
+    final int sourceRow = source[1];
+    final int targetCol = target[0];
+    final int targetRow = target[1];
+
+    // ensure source and target are inside range
+    if (sourceRow < 0 ||
+        sourceRow > (boardSize - 1) ||
+        sourceCol < 0 ||
+        sourceCol > (boardSize - 1)) {
+      // printlog('move forbidden: source is out of board');
+      return false;
+    }
+    if (targetRow < 0 ||
+        targetRow > (boardSize - 1) ||
+        targetCol < 0 ||
+        targetCol > (boardSize - 1)) {
+      // printlog('move forbidden: target is out of board');
+      return false;
+    }
+
+    // ensure source exists and has a peg
+    if (cells[sourceRow][sourceCol].hasPeg == false) {
+      // printlog('move forbidden: source peg does not exist');
+      return false;
+    }
+
+    // ensure target exists and is empty
+    if (cells[targetRow][targetCol].hasPeg == true) {
+      // printlog('move forbidden: target does not exist or already with a peg');
+      return false;
+    }
+
+    // ensure source and target are in the same line/column
+    if ((targetCol != sourceCol) && (targetRow != sourceRow)) {
+      // printlog('move forbidden: source and target are not in the same line or column');
+      return false;
+    }
+
+    // ensure source and target are separated by exactly one tile
+    if (((targetCol == sourceCol) && ((targetRow - sourceRow).abs() != 2)) ||
+        ((targetRow == sourceRow) && ((targetCol - sourceCol).abs() != 2))) {
+      // printlog('move forbidden: source and target must be separated by exactly one tile');
+      return false;
+    }
+
+    // ensure middle tile exists and has a peg
+    final int middleRow = (sourceRow + ((targetRow - sourceRow) / 2)).round();
+    final int middleCol = (sourceCol + ((targetCol - sourceCol) / 2)).round();
+    if (cells[middleRow][middleCol].hasPeg == false) {
+      // printlog('move forbidden: tile between source and target does not contain a peg');
+      return false;
+    }
+
+    // ok, move is allowed
+    return true;
+  }
+
+  void printGrid() {
+    String textBoard = ' ';
+    String textHole = '·';
+    String textPeg = 'o';
+
+    printlog('');
+    printlog('-------');
+    for (int rowIndex = 0; rowIndex < cells.length; rowIndex++) {
+      String row = '';
+      for (int colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) {
+        String textCell = textBoard;
+        Cell tile = cells[rowIndex][colIndex];
+        textCell = tile.hasPeg ? textPeg : textHole;
+        row += textCell;
+      }
+      printlog(row);
+    }
+    printlog('-------');
+    printlog('');
+  }
+
+  void dump() {
+    printlog('');
+    printlog('$Board:');
+    printGrid();
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$Board(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'cells': cells,
+    };
+  }
+}
diff --git a/lib/models/cell.dart b/lib/models/cell.dart
new file mode 100644
index 0000000..127c300
--- /dev/null
+++ b/lib/models/cell.dart
@@ -0,0 +1,41 @@
+import 'package:solitaire/models/cell_location.dart';
+import 'package:solitaire/utils/tools.dart';
+
+class Cell {
+  Cell({
+    required this.location,
+    required this.hasHole,
+    required this.hasPeg,
+  });
+
+  final CellLocation location;
+  bool hasHole;
+  bool hasPeg;
+
+  static Cell none = Cell(
+    location: CellLocation.go(0, 0),
+    hasHole: false,
+    hasPeg: false,
+  );
+
+  void dump() {
+    printlog('$Cell:');
+    printlog('  location: $location');
+    printlog('  hasHole: $hasHole');
+    printlog('  hasPeg: $hasPeg');
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$Cell(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'location': location,
+      'hasHole': hasHole,
+      'hasPeg': hasPeg,
+    };
+  }
+}
diff --git a/lib/models/cell_location.dart b/lib/models/cell_location.dart
new file mode 100644
index 0000000..f9b9022
--- /dev/null
+++ b/lib/models/cell_location.dart
@@ -0,0 +1,34 @@
+import 'package:solitaire/utils/tools.dart';
+
+class CellLocation {
+  final int col;
+  final int row;
+
+  CellLocation({
+    required this.col,
+    required this.row,
+  });
+
+  factory CellLocation.go(int row, int col) {
+    return CellLocation(col: col, row: row);
+  }
+
+  void dump() {
+    printlog('$CellLocation:');
+    printlog('  col: $col');
+    printlog('  row: $row');
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$CellLocation(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'col': col,
+      'row': row,
+    };
+  }
+}
diff --git a/lib/models/game.dart b/lib/models/game.dart
new file mode 100644
index 0000000..009ff4f
--- /dev/null
+++ b/lib/models/game.dart
@@ -0,0 +1,142 @@
+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/utils/tools.dart';
+
+class Game {
+  Game({
+    required this.gameSettings,
+    required this.globalSettings,
+    required this.board,
+    this.isRunning = false,
+    this.isFinished = false,
+    this.movesCount = 0,
+    this.remainingPegsCount = 0,
+    this.allowedMovesCount = 0,
+  });
+
+  final GameSettings gameSettings;
+  final GlobalSettings globalSettings;
+
+  bool isRunning = false;
+  bool isFinished = false;
+
+  Board board;
+
+  int movesCount = 0;
+  int remainingPegsCount = 0;
+  int allowedMovesCount = 0;
+
+  factory Game.createNull() {
+    return Game(
+      gameSettings: GameSettings.createDefault(),
+      globalSettings: GlobalSettings.createDefault(),
+      board: Board.createEmpty(),
+    );
+  }
+
+  factory Game.createNew({
+    GameSettings? gameSettings,
+    GlobalSettings? globalSettings,
+  }) {
+    GameSettings newGameSettings = gameSettings ?? GameSettings.createDefault();
+    GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
+
+    return Game(
+      gameSettings: newGameSettings,
+      globalSettings: newGlobalSettings,
+      board: Board.createNew(
+        gameSettings: newGameSettings,
+      ),
+      isRunning: true,
+    );
+  }
+
+  int get boardSize => board.boardSize;
+
+  bool get gameWon => (isFinished && (remainingPegsCount == 1));
+
+  List<Cell> listRemainingPegs() {
+    final List<Cell> pegs = [];
+
+    final BoardCells cells = board.cells;
+    for (int rowIndex = 0; rowIndex < cells.length; rowIndex++) {
+      for (int colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) {
+        Cell tile = cells[rowIndex][colIndex];
+        if (tile.hasPeg == true) {
+          pegs.add(tile);
+        }
+      }
+    }
+
+    return pegs;
+  }
+
+  int countRemainingPegs() {
+    return listRemainingPegs().length;
+  }
+
+  int countAllowedMoves() {
+    int allowedMovesCount = 0;
+    final List<Cell> pegs = listRemainingPegs();
+    for (Cell tile in pegs) {
+      final int row = tile.location.row;
+      final int col = tile.location.col;
+      final List<int> source = [col, row];
+      final List<List<int>> targets = [
+        [col - 2, row],
+        [col + 2, row],
+        [col, row - 2],
+        [col, row + 2],
+      ];
+      for (List<int> target in targets) {
+        if (board.isMoveAllowed(
+          source: source,
+          target: target,
+        )) {
+          allowedMovesCount++;
+        }
+      }
+    }
+
+    return allowedMovesCount;
+  }
+
+  void dump() {
+    printlog('');
+    printlog('## Current game dump:');
+    printlog('');
+    gameSettings.dump();
+    globalSettings.dump();
+    printlog('');
+    printlog('');
+    printlog('$Game: ');
+    printlog('  isRunning: $isRunning');
+    printlog('  isFinished: $isFinished');
+    printlog('  movesCount: $movesCount');
+    printlog('  remainingPegsCount: $remainingPegsCount');
+    printlog('  allowedMovesCount: $allowedMovesCount');
+    printlog('');
+    board.dump();
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$Game(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      'gameSettings': gameSettings.toJson(),
+      'globalSettings': globalSettings.toJson(),
+      'board': board.toJson(),
+      'isRunning': isRunning,
+      'isFinished': isFinished,
+      'movesCount': movesCount,
+      'remainingPegsCount': remainingPegsCount,
+      'allowedMovesCount': allowedMovesCount,
+    };
+  }
+}
diff --git a/lib/models/settings_game.dart b/lib/models/settings_game.dart
new file mode 100644
index 0000000..cb00bc9
--- /dev/null
+++ b/lib/models/settings_game.dart
@@ -0,0 +1,41 @@
+import 'package:solitaire/config/default_game_settings.dart';
+import 'package:solitaire/utils/tools.dart';
+
+class GameSettings {
+  final String layout;
+
+  GameSettings({
+    required this.layout,
+  });
+
+  static String getLayoutValueFromUnsafe(String layout) {
+    if (DefaultGameSettings.allowedLayoutValues.contains(layout)) {
+      return layout;
+    }
+
+    return DefaultGameSettings.defaultLayoutValue;
+  }
+
+  factory GameSettings.createDefault() {
+    return GameSettings(
+      layout: DefaultGameSettings.defaultLayoutValue,
+    );
+  }
+
+  void dump() {
+    printlog('$GameSettings: ');
+    printlog('  ${DefaultGameSettings.parameterCodeLayout}: $layout');
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$GameSettings(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      DefaultGameSettings.parameterCodeLayout: layout,
+    };
+  }
+}
diff --git a/lib/models/settings_global.dart b/lib/models/settings_global.dart
new file mode 100644
index 0000000..dd4b7c8
--- /dev/null
+++ b/lib/models/settings_global.dart
@@ -0,0 +1,41 @@
+import 'package:solitaire/config/default_global_settings.dart';
+import 'package:solitaire/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/types.dart b/lib/models/types.dart
new file mode 100644
index 0000000..e69de29
diff --git a/lib/provider/data.dart b/lib/provider/data.dart
deleted file mode 100644
index 9c18e79..0000000
--- a/lib/provider/data.dart
+++ /dev/null
@@ -1,239 +0,0 @@
-import 'dart:convert';
-
-import 'package:flutter/foundation.dart';
-import 'package:shared_preferences/shared_preferences.dart';
-import 'package:solitaire/entities/tile.dart';
-import 'package:solitaire/utils/game_utils.dart';
-
-typedef Board = List<List<Tile?>>;
-
-class Data extends ChangeNotifier {
-  // Configuration available values
-  final List<String> _availableParameters = ['layout', 'skin'];
-
-  final List<String> _availableLayoutValues = ['french', 'german', 'english', 'diamond'];
-  final List<String> _availableSkinValues = ['default'];
-
-  List<String> get availableParameters => _availableParameters;
-  List<String> get availableLayoutValues => _availableLayoutValues;
-  List<String> get availableSkinValues => _availableSkinValues;
-
-  // Application default configuration
-  String _parameterLayout = '';
-  String _parameterSkin = '';
-  final String _parameterLayoutDefault = 'english';
-  final String _parameterSkinDefault = 'default';
-
-  // Application current configuration
-  String get parameterLayout => _parameterLayout;
-  String get parameterSkin => _parameterSkin;
-
-  // Game data
-  bool _assetsPreloaded = false;
-  bool _gameIsRunning = false;
-  bool _gameIsFinished = false;
-  Board _board = [];
-  int _boardSize = 0;
-  double _tileSize = 0;
-  int _movesCount = 0;
-  int _remainingPegsCount = 0;
-  int _allowedMovesCount = 0;
-  String _currentState = '';
-
-  void updateParameterLayout(String parameterLayout) {
-    _parameterLayout = parameterLayout;
-    notifyListeners();
-  }
-
-  void updateParameterSkin(String parameterSkin) {
-    _parameterSkin = parameterSkin;
-    notifyListeners();
-  }
-
-  String getParameterValue(String parameterCode) {
-    switch (parameterCode) {
-      case 'layout':
-        return _parameterLayout;
-      case 'skin':
-        return _parameterSkin;
-    }
-    return '';
-  }
-
-  List getParameterAvailableValues(String parameterCode) {
-    switch (parameterCode) {
-      case 'layout':
-        return _availableLayoutValues;
-      case 'skin':
-        return _availableSkinValues;
-    }
-    return [];
-  }
-
-  void setParameterValue(String parameterCode, String parameterValue) async {
-    switch (parameterCode) {
-      case 'layout':
-        updateParameterLayout(parameterValue);
-        break;
-      case 'skin':
-        updateParameterSkin(parameterValue);
-        break;
-    }
-    final prefs = await SharedPreferences.getInstance();
-    prefs.setString(parameterCode, parameterValue);
-  }
-
-  void initParametersValues() async {
-    final prefs = await SharedPreferences.getInstance();
-    setParameterValue('layout', prefs.getString('layout') ?? _parameterLayoutDefault);
-    setParameterValue('skin', prefs.getString('skin') ?? _parameterSkinDefault);
-  }
-
-  String get currentState => _currentState;
-
-  String computeCurrentGameState() {
-    String boardValues = '';
-
-    String textBoard = ' ';
-    String textHole = '·';
-    String textPeg = 'o';
-    for (int rowIndex = 0; rowIndex < _board.length; rowIndex++) {
-      for (int colIndex = 0; colIndex < _board[rowIndex].length; colIndex++) {
-        String cellValue = textBoard;
-        if (_board[rowIndex][colIndex] != null) {
-          cellValue = (_board[rowIndex][colIndex]?.hasPeg ?? false) ? textPeg : textHole;
-        }
-        boardValues += cellValue;
-      }
-    }
-
-    var currentState = {
-      'layout': _parameterLayout,
-      'skin': _parameterSkin,
-      'movesCount': _movesCount.toString(),
-      'boardValues': boardValues,
-    };
-
-    return json.encode(currentState);
-  }
-
-  void saveCurrentGameState() async {
-    if (_gameIsRunning) {
-      _currentState = computeCurrentGameState();
-
-      final prefs = await SharedPreferences.getInstance();
-      prefs.setString('savedState', _currentState);
-    } else {
-      resetCurrentSavedState();
-    }
-  }
-
-  void resetCurrentSavedState() async {
-    _currentState = '';
-
-    final prefs = await SharedPreferences.getInstance();
-    prefs.setString('savedState', _currentState);
-    notifyListeners();
-  }
-
-  void loadCurrentSavedState() async {
-    final prefs = await SharedPreferences.getInstance();
-    _currentState = prefs.getString('savedState') ?? '';
-  }
-
-  bool hasCurrentSavedState() {
-    return (_currentState != '');
-  }
-
-  Map<String, dynamic> getCurrentSavedState() {
-    if (_currentState != '') {
-      final Map<String, dynamic> savedState = json.decode(_currentState);
-      if (savedState.isNotEmpty) {
-        return savedState;
-      }
-    }
-    return {};
-  }
-
-  bool get assetsPreloaded => _assetsPreloaded;
-  void updateAssetsPreloaded(bool assetsPreloaded) {
-    _assetsPreloaded = assetsPreloaded;
-  }
-
-  double get tileSize => _tileSize;
-  void updateTileSize(double tileSize) {
-    _tileSize = tileSize;
-  }
-
-  int get boardSize => _boardSize;
-  void updateBoardSize(int boardSize) {
-    _boardSize = boardSize;
-  }
-
-  Board get board => _board;
-  void updateBoard(Board board) {
-    _board = board;
-    updateBoardSize(board.length);
-    updateRemainingPegsCount(GameUtils.countRemainingPegs(this));
-    updateAllowedMovesCount(GameUtils.countAllowedMoves(this));
-    notifyListeners();
-  }
-
-  updatePegValue(int row, int col, bool hasPeg) {
-    if (_board[row][col] != null) {
-      _board[row][col]?.hasPeg = hasPeg;
-
-      saveCurrentGameState();
-      notifyListeners();
-    }
-  }
-
-  int get movesCount => _movesCount;
-  void updateMovesCount(int movesCount) {
-    _movesCount = movesCount;
-    notifyListeners();
-  }
-
-  void incrementMovesCount() {
-    updateMovesCount(movesCount + 1);
-  }
-
-  int get remainingPegsCount => _remainingPegsCount;
-  void updateRemainingPegsCount(int remainingPegsCount) {
-    _remainingPegsCount = remainingPegsCount;
-    notifyListeners();
-  }
-
-  int get allowedMovesCount => _allowedMovesCount;
-  void updateAllowedMovesCount(int allowedMovesCount) {
-    _allowedMovesCount = allowedMovesCount;
-    if (allowedMovesCount == 0) {
-      updateGameIsFinished(true);
-    }
-    notifyListeners();
-  }
-
-  bool get gameIsRunning => _gameIsRunning;
-  bool get gameIsFinished => _gameIsFinished;
-  void updateGameIsRunning(bool gameIsRunning) {
-    _gameIsRunning = gameIsRunning;
-    notifyListeners();
-  }
-
-  void updateGameIsFinished(bool gameIsFinished) {
-    _gameIsFinished = gameIsFinished;
-    notifyListeners();
-  }
-
-  bool gameWon() {
-    return gameIsFinished && (remainingPegsCount == 1);
-  }
-
-  void resetGame() {
-    _gameIsRunning = false;
-    _gameIsFinished = false;
-    _movesCount = 0;
-    _remainingPegsCount = 0;
-    notifyListeners();
-  }
-}
diff --git a/lib/ui/layout/game.dart b/lib/ui/layout/game.dart
deleted file mode 100644
index aa9d47c..0000000
--- a/lib/ui/layout/game.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/ui/layout/tileset.dart';
-import 'package:solitaire/ui/widgets/game/indicator_top.dart';
-import 'package:solitaire/ui/widgets/game/message_game_end.dart';
-
-class Game extends StatelessWidget {
-  const Game({super.key, required this.myProvider});
-
-  final Data myProvider;
-
-  @override
-  Widget build(BuildContext context) {
-    final bool gameIsFinished = myProvider.gameIsFinished;
-
-    return Column(
-      mainAxisAlignment: MainAxisAlignment.start,
-      crossAxisAlignment: CrossAxisAlignment.center,
-      children: [
-        const SizedBox(height: 8),
-        TopIndicator(myProvider: myProvider),
-        const SizedBox(height: 2),
-        Expanded(
-          child: Tileset(myProvider: myProvider),
-        ),
-        const SizedBox(height: 2),
-        Container(
-          child: gameIsFinished
-              ? EndGameMessage(myProvider: myProvider)
-              : const SizedBox(height: 2),
-        ),
-      ],
-    );
-  }
-}
diff --git a/lib/ui/layout/parameters.dart b/lib/ui/layout/parameters.dart
deleted file mode 100644
index 68d9ac8..0000000
--- a/lib/ui/layout/parameters.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/ui/widgets/home/button_game_resume.dart';
-import 'package:solitaire/ui/widgets/home/button_game_start_new.dart';
-
-class Parameters extends StatelessWidget {
-  const Parameters({super.key, required this.myProvider});
-
-  final Data myProvider;
-
-  static const double separatorHeight = 2.0;
-  static const double blockMargin = 0.0;
-  static const double blockPadding = 0.0;
-  static const Color buttonBackgroundColor = Colors.white;
-  static const Color buttonBorderColorActive = Colors.blue;
-  static const Color buttonBorderColorInactive = Colors.white;
-  static const double buttonBorderWidth = 6.0;
-  static const double buttonBorderRadius = 8.0;
-  static const double buttonPadding = 0.0;
-  static const double buttonMargin = 0.0;
-
-  @override
-  Widget build(BuildContext context) {
-    List<Widget> lines = [];
-
-    List parameters = myProvider.availableParameters;
-    for (int index = 0; index < parameters.length; index++) {
-      lines.add(buildParameterSelector(myProvider, parameters[index]));
-      lines.add(const SizedBox(height: separatorHeight));
-    }
-
-    myProvider.loadCurrentSavedState();
-    Widget buttonsBlock = myProvider.hasCurrentSavedState()
-        ? ResumeGameButton(myProvider: myProvider)
-        : StartNewGameButton(myProvider: myProvider);
-
-    return Column(
-      mainAxisAlignment: MainAxisAlignment.start,
-      crossAxisAlignment: CrossAxisAlignment.center,
-      children: [
-        const SizedBox(height: separatorHeight),
-        Expanded(
-          child: Column(
-            mainAxisSize: MainAxisSize.min,
-            mainAxisAlignment: MainAxisAlignment.center,
-            children: lines,
-          ),
-        ),
-        const SizedBox(height: separatorHeight),
-        Container(
-          child: buttonsBlock,
-        ),
-      ],
-    );
-  }
-
-  static Image buildImageWidget(String imageAssetCode) {
-    return Image(
-      image: AssetImage('assets/icons/$imageAssetCode.png'),
-      fit: BoxFit.fill,
-    );
-  }
-
-  static Container buildImageContainerWidget(String imageAssetCode) {
-    return Container(
-      child: buildImageWidget(imageAssetCode),
-    );
-  }
-
-  static Column buildDecorationImageWidget() {
-    return Column(
-      children: [
-        TextButton(
-          child: buildImageContainerWidget('placeholder'),
-          onPressed: () {},
-        ),
-      ],
-    );
-  }
-
-  Widget buildParameterSelector(Data myProvider, String parameterCode) {
-    List availableValues = myProvider.getParameterAvailableValues(parameterCode);
-
-    if (availableValues.length == 1) {
-      return const SizedBox(height: 0.0);
-    }
-
-    return Table(
-      defaultColumnWidth: const IntrinsicColumnWidth(),
-      children: [
-        TableRow(
-          children: [
-            for (int index = 0; index < availableValues.length; index++)
-              Column(
-                children: [
-                  buildParameterButton(myProvider, parameterCode, availableValues[index])
-                ],
-              ),
-          ],
-        ),
-      ],
-    );
-  }
-
-  Widget buildParameterButton(Data myProvider, String parameterCode, String parameterValue) {
-    String currentValue = myProvider.getParameterValue(parameterCode).toString();
-
-    bool isActive = (parameterValue == currentValue);
-    String imageAsset = '${parameterCode}_$parameterValue';
-
-    return TextButton(
-      child: Container(
-        margin: const EdgeInsets.all(buttonMargin),
-        padding: const EdgeInsets.all(buttonPadding),
-        decoration: BoxDecoration(
-          color: buttonBackgroundColor,
-          borderRadius: BorderRadius.circular(buttonBorderRadius),
-          border: Border.all(
-            color: isActive ? buttonBorderColorActive : buttonBorderColorInactive,
-            width: buttonBorderWidth,
-          ),
-        ),
-        child: buildImageWidget(imageAsset),
-      ),
-      onPressed: () => myProvider.setParameterValue(parameterCode, parameterValue),
-    );
-  }
-}
diff --git a/lib/ui/layout/tileset.dart b/lib/ui/layout/tileset.dart
deleted file mode 100644
index 4fe85a7..0000000
--- a/lib/ui/layout/tileset.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:solitaire/provider/data.dart';
-
-class Tileset extends StatelessWidget {
-  const Tileset({super.key, required this.myProvider});
-
-  final Data myProvider;
-
-  @override
-  Widget build(BuildContext context) {
-    final Board board = myProvider.board;
-
-    Widget boardTileWithoutHole = Image(
-      image: AssetImage('assets/skins/${myProvider.parameterSkin}_board.png'),
-      width: myProvider.tileSize,
-      height: myProvider.tileSize,
-      fit: BoxFit.fill,
-    );
-
-    return Column(
-      children: [
-        Table(
-          defaultColumnWidth: const IntrinsicColumnWidth(),
-          children: [
-            for (int row = 0; row < board.length; row++)
-              TableRow(
-                children: [
-                  for (int col = 0; col < board[row].length; col++)
-                    TableCell(
-                      child: board[row][col] != null
-                          ? (board[row][col]?.render(myProvider) ?? Container())
-                          : boardTileWithoutHole,
-                    ),
-                ],
-              ),
-          ],
-        ),
-      ],
-    );
-  }
-}
diff --git a/lib/ui/painters/parameter_painter.dart b/lib/ui/painters/parameter_painter.dart
new file mode 100644
index 0000000..4ed92d7
--- /dev/null
+++ b/lib/ui/painters/parameter_painter.dart
@@ -0,0 +1,190 @@
+import 'dart:math';
+
+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/utils/tools.dart';
+
+class ParameterPainter extends CustomPainter {
+  const ParameterPainter({
+    required this.code,
+    required this.value,
+    required this.isSelected,
+    required this.gameSettings,
+    required this.globalSettings,
+  });
+
+  final String code;
+  final String value;
+  final bool isSelected;
+  final GameSettings gameSettings;
+  final GlobalSettings globalSettings;
+
+  @override
+  void paint(Canvas canvas, Size size) {
+    // force square
+    final double canvasSize = min(size.width, size.height);
+
+    const Color borderColorEnabled = Colors.blue;
+    const Color borderColorDisabled = Colors.white;
+
+    // "enabled/disabled" border
+    final paint = Paint();
+    paint.style = PaintingStyle.stroke;
+    paint.color = isSelected ? borderColorEnabled : borderColorDisabled;
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 10;
+    canvas.drawRect(
+        Rect.fromPoints(const Offset(0, 0), Offset(canvasSize, canvasSize)), paint);
+
+    // content
+    switch (code) {
+      case DefaultGameSettings.parameterCodeLayout:
+        paintLayoutParameterItem(value, canvas, canvasSize);
+        break;
+      default:
+        printlog('Unknown parameter: $code/$value');
+        paintUnknownParameterItem(value, canvas, canvasSize);
+    }
+  }
+
+  @override
+  bool shouldRepaint(CustomPainter oldDelegate) {
+    return false;
+  }
+
+  // "unknown" parameter -> simple block with text
+  void paintUnknownParameterItem(
+    final String value,
+    final Canvas canvas,
+    final double size,
+  ) {
+    final paint = Paint();
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 3;
+
+    paint.color = Colors.grey;
+    paint.style = PaintingStyle.fill;
+    canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
+
+    final textSpan = TextSpan(
+      text: '?\n$value',
+      style: const TextStyle(
+        color: Colors.black,
+        fontSize: 18,
+        fontWeight: FontWeight.bold,
+      ),
+    );
+    final textPainter = TextPainter(
+      text: textSpan,
+      textDirection: TextDirection.ltr,
+      textAlign: TextAlign.center,
+    );
+    textPainter.layout();
+    textPainter.paint(
+      canvas,
+      Offset(
+        (size - textPainter.width) * 0.5,
+        (size - textPainter.height) * 0.5,
+      ),
+    );
+  }
+
+  void paintLayoutParameterItem(
+    final String value,
+    final Canvas canvas,
+    final double size,
+  ) {
+    {
+      const Color backgroundColor = Colors.white;
+
+      Color gridBackgroundColor = Colors.grey;
+
+      switch (value) {
+        case DefaultGameSettings.layoutValueFrench:
+          gridBackgroundColor = Colors.green;
+          break;
+        case DefaultGameSettings.layoutValueGerman:
+          gridBackgroundColor = Colors.orange;
+          break;
+        case DefaultGameSettings.layoutValueEnglish:
+          gridBackgroundColor = Colors.red;
+          break;
+        case DefaultGameSettings.layoutValueDiamond:
+          gridBackgroundColor = Colors.purple;
+          break;
+        default:
+          printlog('Wrong value for size parameter value: $value');
+      }
+
+      final paint = Paint();
+      paint.strokeJoin = StrokeJoin.round;
+      paint.strokeWidth = 3;
+
+      // Colored background
+      paint.color = backgroundColor;
+      paint.style = PaintingStyle.fill;
+      canvas.drawRect(Rect.fromPoints(const Offset(0, 0), Offset(size, size)), paint);
+
+      // Mini grid
+      final borderColor = Colors.grey.shade800;
+
+      // Get board data from named templates
+      final List<String>? template = GameData.templates[value];
+      final BoardCells grid = [];
+
+      int row = 0;
+      template?.forEach((String line) {
+        final List<Cell> gridLine = [];
+        int col = 0;
+        line.split("").forEach((String tileCode) {
+          gridLine.add(tileCode == ' '
+              ? Cell.none
+              : Cell(
+                  location: CellLocation.go(row, col),
+                  hasHole: true,
+                  hasPeg: (tileCode == 'o'),
+                ));
+          col++;
+        });
+        row++;
+        grid.add(gridLine);
+      });
+
+      final int gridWidth = grid.length;
+      final int gridHeight = grid.first.length;
+      paint.strokeWidth = 2;
+
+      final double cellSize = (size * .9) / max(gridWidth, gridHeight);
+      final double originX = (size - gridWidth * cellSize) / 2;
+      final double originY = (size - gridHeight * cellSize) / 2;
+
+      for (int row = 0; row < gridHeight; row++) {
+        for (int col = 0; col < gridWidth; col++) {
+          final Offset topLeft = Offset(originX + col * cellSize, originY + row * cellSize);
+          final Offset bottomRight = topLeft + Offset(cellSize, cellSize);
+
+          paint.color = Colors.white;
+          paint.style = PaintingStyle.fill;
+
+          if (grid[row][col].hasPeg) {
+            paint.color = gridBackgroundColor;
+          }
+          canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+
+          if (grid[row][col].hasHole) {
+            paint.color = borderColor;
+            paint.style = PaintingStyle.stroke;
+            canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/lib/ui/screens/game_page.dart b/lib/ui/screens/game_page.dart
deleted file mode 100644
index 9171fc2..0000000
--- a/lib/ui/screens/game_page.dart
+++ /dev/null
@@ -1,85 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:provider/provider.dart';
-
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/ui/layout/game.dart';
-import 'package:solitaire/ui/layout/parameters.dart';
-
-class GamePage extends StatefulWidget {
-  const GamePage({super.key});
-
-  @override
-  GamePageState createState() => GamePageState();
-}
-
-class GamePageState extends State<GamePage> {
-  @override
-  void initState() {
-    super.initState();
-
-    final Data myProvider = Provider.of<Data>(context, listen: false);
-    myProvider.initParametersValues();
-    myProvider.loadCurrentSavedState();
-  }
-
-  List<String> getImagesAssets(Data myProvider) {
-    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 layout in myProvider.availableLayoutValues) {
-      gameImages.add('layout_$layout');
-    }
-    for (String skin in myProvider.availableSkinValues) {
-      gameImages.add('skin_$skin');
-    }
-
-    for (String image in gameImages) {
-      assets.add('${'assets/icons/$image'}.png');
-    }
-
-    const List<String> skinImages = [
-      'board',
-      'hole',
-      'peg',
-    ];
-
-    for (String skin in myProvider.availableSkinValues) {
-      for (String image in skinImages) {
-        assets.add('${'${'assets/skins/$skin'}_$image'}.png');
-      }
-    }
-
-    return assets;
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    final Data myProvider = Provider.of<Data>(context);
-
-    if (!myProvider.assetsPreloaded) {
-      final List<String> assets = getImagesAssets(myProvider);
-      for (String asset in assets) {
-        precacheImage(AssetImage(asset), context);
-      }
-      myProvider.updateAssetsPreloaded(true);
-    }
-
-    myProvider.updateTileSize((MediaQuery.of(context).size.width - 40) / myProvider.boardSize);
-
-    return SafeArea(
-      child: Center(
-        child: myProvider.gameIsRunning
-            ? Game(myProvider: myProvider)
-            : Parameters(myProvider: myProvider),
-      ),
-    );
-  }
-}
diff --git a/lib/ui/screens/about_page.dart b/lib/ui/screens/page_about.dart
similarity index 89%
rename from lib/ui/screens/about_page.dart
rename to lib/ui/screens/page_about.dart
index f22e2ad..f63e153 100644
--- a/lib/ui/screens/about_page.dart
+++ b/lib/ui/screens/page_about.dart
@@ -2,10 +2,10 @@ 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/header_app.dart';
+import 'package:solitaire/ui/widgets/helpers/app_header.dart';
 
-class AboutPage extends StatelessWidget {
-  const AboutPage({super.key});
+class PageAbout extends StatelessWidget {
+  const PageAbout({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/screens/page_game.dart b/lib/ui/screens/page_game.dart
new file mode 100644
index 0000000..287a383
--- /dev/null
+++ b/lib/ui/screens/page_game.dart
@@ -0,0 +1,19 @@
+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';
+
+class PageGame extends StatelessWidget {
+  const PageGame({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        return gameState.currentGame.isRunning ? const GameWidget() : const Parameters();
+      },
+    );
+  }
+}
diff --git a/lib/ui/screens/settings_page.dart b/lib/ui/screens/page_settings.dart
similarity index 80%
rename from lib/ui/screens/settings_page.dart
rename to lib/ui/screens/page_settings.dart
index 63cb3f2..ae65ab9 100644
--- a/lib/ui/screens/settings_page.dart
+++ b/lib/ui/screens/page_settings.dart
@@ -1,10 +1,10 @@
 import 'package:flutter/material.dart';
 
-import 'package:solitaire/ui/widgets/header_app.dart';
+import 'package:solitaire/ui/widgets/helpers/app_header.dart';
 import 'package:solitaire/ui/widgets/settings/settings_form.dart';
 
-class SettingsPage extends StatelessWidget {
-  const SettingsPage({super.key});
+class PageSettings extends StatelessWidget {
+  const PageSettings({super.key});
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index 36cd485..c57f5c2 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -1,32 +1,33 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:provider/provider.dart';
 
 import 'package:solitaire/config/menu.dart';
-import 'package:solitaire/cubit/bottom_nav_cubit.dart';
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/ui/widgets/app_bar.dart';
-import 'package:solitaire/ui/widgets/bottom_nav_bar.dart';
+import 'package:solitaire/cubit/nav_cubit.dart';
+import 'package:solitaire/ui/widgets/global_app_bar.dart';
 
-class SkeletonScreen extends StatefulWidget {
+class SkeletonScreen extends StatelessWidget {
   const SkeletonScreen({super.key});
 
-  @override
-  State<SkeletonScreen> createState() => _SkeletonScreenState();
-}
-
-class _SkeletonScreenState extends State<SkeletonScreen> {
   @override
   Widget build(BuildContext context) {
-    final Data myProvider = Provider.of<Data>(context);
-
     return Scaffold(
+      appBar: const GlobalAppBar(),
       extendBodyBehindAppBar: false,
-      appBar: StandardAppBar(myProvider: myProvider),
-      bottomNavigationBar: const BottomNavBar(),
-      body: BlocBuilder<BottomNavCubit, int>(builder: (BuildContext context, int state) {
-        return Menu.getPageWidget(state);
-      }),
+      body: Material(
+        color: Theme.of(context).colorScheme.background,
+        child: BlocBuilder<NavCubit, int>(
+          builder: (BuildContext context, int pageIndex) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                top: 8,
+                left: 2,
+                right: 2,
+              ),
+              child: Menu.getPageWidget(pageIndex),
+            );
+          },
+        ),
+      ),
       backgroundColor: Theme.of(context).colorScheme.background,
     );
   }
diff --git a/lib/ui/widgets/app_bar.dart b/lib/ui/widgets/app_bar.dart
deleted file mode 100644
index 1dc274e..0000000
--- a/lib/ui/widgets/app_bar.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-import 'package:overlay_support/overlay_support.dart';
-
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/ui/widgets/header_app.dart';
-import 'package:solitaire/utils/game_utils.dart';
-
-class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
-  const StandardAppBar({super.key, required this.myProvider});
-
-  final Data myProvider;
-
-  @override
-  Widget build(BuildContext context) {
-    final List<Widget> menuActions = [];
-
-    if (myProvider.gameIsRunning) {
-      menuActions.add(TextButton(
-        child: const Image(
-          image: AssetImage('assets/icons/button_back.png'),
-          fit: BoxFit.fill,
-        ),
-        onPressed: () => toast(tr('long_press_to_quit')),
-        onLongPress: () => GameUtils.quitGame(myProvider),
-      ));
-    }
-
-    return AppBar(
-      title: const AppHeader(text: 'app_name'),
-      actions: menuActions,
-    );
-  }
-
-  @override
-  Size get preferredSize => const Size.fromHeight(50);
-}
diff --git a/lib/ui/widgets/bottom_nav_bar.dart b/lib/ui/widgets/bottom_nav_bar.dart
deleted file mode 100644
index 7e3d471..0000000
--- a/lib/ui/widgets/bottom_nav_bar.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-
-import 'package:solitaire/config/menu.dart';
-import 'package:solitaire/cubit/bottom_nav_cubit.dart';
-
-class BottomNavBar extends StatelessWidget {
-  const BottomNavBar({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return Card(
-      margin: const EdgeInsets.all(0),
-      elevation: 4,
-      shadowColor: Theme.of(context).colorScheme.shadow,
-      color: Theme.of(context).colorScheme.surfaceVariant,
-      shape: const ContinuousRectangleBorder(),
-      child: BlocBuilder<BottomNavCubit, int>(
-        builder: (BuildContext context, int state) {
-          return BottomNavigationBar(
-            currentIndex: state,
-            onTap: (int index) {
-              context.read<BottomNavCubit>().updateIndex(index);
-            },
-            type: BottomNavigationBarType.fixed,
-            elevation: 0,
-            backgroundColor: Colors.transparent,
-            selectedItemColor: Theme.of(context).colorScheme.primary,
-            unselectedItemColor: Theme.of(context).textTheme.bodySmall!.color,
-            items: Menu.getMenuItems(),
-          );
-        },
-      ),
-    );
-  }
-}
diff --git a/lib/ui/widgets/button_game_start_new.dart b/lib/ui/widgets/button_game_start_new.dart
new file mode 100644
index 0000000..cd4b8f0
--- /dev/null
+++ b/lib/ui/widgets/button_game_start_new.dart
@@ -0,0 +1,34 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+import 'package:solitaire/cubit/game_cubit.dart';
+import 'package:solitaire/cubit/settings_game_cubit.dart';
+import 'package:solitaire/cubit/settings_global_cubit.dart';
+
+class StartNewGameButton extends StatelessWidget {
+  const StartNewGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameSettingsCubit, GameSettingsState>(
+      builder: (BuildContext context, GameSettingsState gameSettingsState) {
+        return BlocBuilder<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'),
+                fit: BoxFit.fill,
+              ),
+              onPressed: () => gameCubit.startNewGame(
+                gameSettings: gameSettingsState.settings,
+                globalSettings: globalSettingsState.settings,
+              ),
+            );
+          },
+        );
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/game/game_widget.dart b/lib/ui/widgets/game/game_widget.dart
new file mode 100644
index 0000000..e2c7caf
--- /dev/null
+++ b/lib/ui/widgets/game/game_widget.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.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/indicator_top.dart b/lib/ui/widgets/game/indicator_top.dart
index 7ce0c3e..bc66f79 100644
--- a/lib/ui/widgets/game/indicator_top.dart
+++ b/lib/ui/widgets/game/indicator_top.dart
@@ -1,47 +1,51 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 
-import 'package:solitaire/provider/data.dart';
+import 'package:solitaire/cubit/game_cubit.dart';
+import 'package:solitaire/models/game.dart';
 
 class TopIndicator extends StatelessWidget {
-  const TopIndicator({super.key, required this.myProvider});
-
-  final Data myProvider;
+  const TopIndicator({super.key});
 
   @override
   Widget build(BuildContext context) {
-    final int allowedMovesCount = myProvider.allowedMovesCount;
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        final Game currentGame = gameState.currentGame;
 
-    return Table(
-      children: [
-        TableRow(
+        return Table(
           children: [
-            Column(
+            TableRow(
               children: [
-                Text(
-                  '♟️ ${myProvider.remainingPegsCount}',
-                  style: const TextStyle(
-                    fontSize: 40,
-                    fontWeight: FontWeight.w600,
-                    color: Colors.black,
-                  ),
+                Column(
+                  children: [
+                    Text(
+                      '♟️ ${currentGame.remainingPegsCount}',
+                      style: const TextStyle(
+                        fontSize: 40,
+                        fontWeight: FontWeight.w600,
+                        color: Colors.black,
+                      ),
+                    ),
+                  ],
                 ),
-              ],
-            ),
-            Column(
-              children: [
-                Text(
-                  allowedMovesCount.toString(),
-                  style: const TextStyle(
-                    fontSize: 20,
-                    fontWeight: FontWeight.w600,
-                    color: Colors.green,
-                  ),
+                Column(
+                  children: [
+                    Text(
+                      currentGame.allowedMovesCount.toString(),
+                      style: const TextStyle(
+                        fontSize: 20,
+                        fontWeight: FontWeight.w600,
+                        color: Colors.green,
+                      ),
+                    ),
+                  ],
                 ),
               ],
             ),
           ],
-        ),
-      ],
+        );
+      },
     );
   }
 }
diff --git a/lib/ui/widgets/game/message_game_end.dart b/lib/ui/widgets/game/message_game_end.dart
index cd6ca3a..b1b4faa 100644
--- a/lib/ui/widgets/game/message_game_end.dart
+++ b/lib/ui/widgets/game/message_game_end.dart
@@ -1,42 +1,56 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
 
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/ui/widgets/home/button_game_restart.dart';
+import 'package:solitaire/cubit/game_cubit.dart';
+import 'package:solitaire/models/game.dart';
 
 class EndGameMessage extends StatelessWidget {
-  const EndGameMessage({super.key, required this.myProvider});
-
-  final Data myProvider;
+  const EndGameMessage({super.key});
 
   @override
   Widget build(BuildContext context) {
-    String decorationImageAssetName = '';
-    if (myProvider.gameWon()) {
-      decorationImageAssetName = 'assets/icons/game_win.png';
-    } else {
-      decorationImageAssetName = 'assets/icons/placeholder.png';
-    }
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        final Game currentGame = gameState.currentGame;
 
-    final Image decorationImage = Image(
-      image: AssetImage(decorationImageAssetName),
-      fit: BoxFit.fill,
-    );
+        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(
+        return Container(
+          margin: const EdgeInsets.all(2),
+          padding: const EdgeInsets.all(2),
+          child: Table(
+            defaultColumnWidth: const IntrinsicColumnWidth(),
             children: [
-              Column(children: [decorationImage]),
-              Column(children: [RestartGameButton(myProvider: myProvider)]),
-              Column(children: [decorationImage]),
+              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
new file mode 100644
index 0000000..7d71df5
--- /dev/null
+++ b/lib/ui/widgets/game/tile_widget.dart
@@ -0,0 +1,135 @@
+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';
+
+class TileWidget extends StatelessWidget {
+  const TileWidget({
+    super.key,
+    required this.tile,
+    required this.tileSize,
+  });
+
+  final Cell tile;
+  final double tileSize;
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(
+      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,
+          );
+        } else {
+          return Image(
+            image: AssetImage('assets/skins/${currentGame.globalSettings.skin}_board.png'),
+            width: tileSize,
+            height: tileSize,
+            fit: BoxFit.fill,
+          );
+        }
+      },
+    );
+  }
+
+  Widget render({
+    required Game currentGame,
+    required GameCubit gameCubit,
+  }) {
+    List<Widget> stack = [
+      hole(
+        currentGame: currentGame,
+        gameCubit: gameCubit,
+      ),
+    ];
+
+    if (tile.hasPeg) {
+      stack.add(draggable(
+        currentGame: currentGame,
+      ));
+    }
+
+    return Stack(
+      alignment: Alignment.center,
+      children: stack,
+    );
+  }
+
+  Widget hole({
+    required Game currentGame,
+    required GameCubit gameCubit,
+  }) {
+    String image = 'assets/skins/${currentGame.globalSettings.skin}_hole.png';
+
+    return DragTarget<List<int>>(
+      builder: (
+        BuildContext context,
+        List<dynamic> accepted,
+        List<dynamic> rejected,
+      ) {
+        return Image(
+          image: AssetImage(image),
+          width: tileSize,
+          height: tileSize,
+          fit: BoxFit.fill,
+        );
+      },
+      onAcceptWithDetails: (DragTargetDetails<List<int>> source) {
+        List<int> target = [tile.location.col, tile.location.row];
+        // printlog('(drag) Pick from ' + source.toString() + ' and drop on ' + target.toString());
+        if (currentGame.board.isMoveAllowed(
+          source: source.data,
+          target: target,
+        )) {
+          gameCubit.move(
+            currentGame: currentGame,
+            source: source.data,
+            target: target,
+          );
+        }
+      },
+    );
+  }
+
+  Widget draggable({
+    required Game currentGame,
+  }) {
+    return Draggable<List<int>>(
+      data: [tile.location.col, tile.location.row],
+
+      // Widget when draggable is being dragged
+      feedback: peg(
+        currentGame: currentGame,
+      ),
+
+      // Widget to display on original place when being dragged
+      childWhenDragging: Container(),
+
+      // Widget when draggable is stationary
+      child: peg(
+        currentGame: currentGame,
+      ),
+    );
+  }
+
+  Widget peg({
+    required Game currentGame,
+  }) {
+    String image = 'assets/skins/${currentGame.globalSettings.skin}_peg.png';
+
+    return Image(
+      image: AssetImage(image),
+      width: tileSize,
+      height: tileSize,
+      fit: BoxFit.fill,
+    );
+  }
+}
diff --git a/lib/ui/widgets/game/tileset.dart b/lib/ui/widgets/game/tileset.dart
new file mode 100644
index 0000000..5462a79
--- /dev/null
+++ b/lib/ui/widgets/game/tileset.dart
@@ -0,0 +1,45 @@
+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/ui/widgets/game/tile_widget.dart';
+
+class Tileset extends StatelessWidget {
+  const Tileset({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        final Board board = gameState.currentGame.board;
+        final BoardCells cells = board.cells;
+
+        final boardSize = gameState.currentGame.boardSize;
+        final double tileSize = (MediaQuery.of(context).size.width - 40) / boardSize;
+
+        return Column(
+          children: [
+            Table(
+              defaultColumnWidth: const IntrinsicColumnWidth(),
+              children: [
+                for (int row = 0; row < cells.length; row++)
+                  TableRow(
+                    children: [
+                      for (int col = 0; col < cells[row].length; col++)
+                        TableCell(
+                          child: TileWidget(
+                            tile: cells[row][col],
+                            tileSize: tileSize,
+                          ),
+                        ),
+                    ],
+                  ),
+              ],
+            ),
+          ],
+        );
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/global_app_bar.dart b/lib/ui/widgets/global_app_bar.dart
new file mode 100644
index 0000000..8212103
--- /dev/null
+++ b/lib/ui/widgets/global_app_bar.dart
@@ -0,0 +1,84 @@
+import 'package:flutter/material.dart';
+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';
+
+class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
+  const GlobalAppBar({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<GameCubit, GameState>(
+      builder: (BuildContext context, GameState gameState) {
+        return BlocBuilder<NavCubit, int>(
+          builder: (BuildContext context, int pageIndex) {
+            final Game currentGame = gameState.currentGame;
+
+            final List<Widget> menuActions = [];
+
+            if (currentGame.isRunning) {
+              menuActions.add(TextButton(
+                child: const Image(
+                  image: AssetImage('assets/icons/button_back.png'),
+                  fit: BoxFit.fill,
+                ),
+                onPressed: () {},
+                onLongPress: () {
+                  final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
+                  gameCubit.quitGame();
+                },
+              ));
+            } else {
+              if (pageIndex == Menu.indexGame) {
+                // go to Settings page
+                menuActions.add(ElevatedButton(
+                  onPressed: () {
+                    context.read<NavCubit>().goToSettingsPage();
+                  },
+                  style: ElevatedButton.styleFrom(
+                    shape: const CircleBorder(),
+                  ),
+                  child: Menu.menuItemSettings.icon,
+                ));
+
+                // go to About page
+                menuActions.add(ElevatedButton(
+                  onPressed: () {
+                    context.read<NavCubit>().goToAboutPage();
+                  },
+                  style: ElevatedButton.styleFrom(
+                    shape: const CircleBorder(),
+                  ),
+                  child: Menu.menuItemAbout.icon,
+                ));
+              } else {
+                // back to Home page
+                menuActions.add(ElevatedButton(
+                  onPressed: () {
+                    context.read<NavCubit>().goToGamePage();
+                  },
+                  style: ElevatedButton.styleFrom(
+                    shape: const CircleBorder(),
+                  ),
+                  child: Menu.menuItemGame.icon,
+                ));
+              }
+            }
+
+            return AppBar(
+              title: const AppTitle(text: 'app_name'),
+              actions: menuActions,
+            );
+          },
+        );
+      },
+    );
+  }
+
+  @override
+  Size get preferredSize => const Size.fromHeight(50);
+}
diff --git a/lib/ui/widgets/header_app.dart b/lib/ui/widgets/helpers/app_header.dart
similarity index 77%
rename from lib/ui/widgets/header_app.dart
rename to lib/ui/widgets/helpers/app_header.dart
index bf54b77..b5c5be0 100644
--- a/lib/ui/widgets/header_app.dart
+++ b/lib/ui/widgets/helpers/app_header.dart
@@ -8,15 +8,16 @@ class AppHeader extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Row(
+    return Column(
       mainAxisAlignment: MainAxisAlignment.start,
       crossAxisAlignment: CrossAxisAlignment.start,
       children: [
         Text(
           tr(text),
           textAlign: TextAlign.start,
-          style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
+          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
new file mode 100644
index 0000000..7cbbb20
--- /dev/null
+++ b/lib/ui/widgets/helpers/app_title.dart
@@ -0,0 +1,17 @@
+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/ui/widgets/home/button_game_restart.dart b/lib/ui/widgets/home/button_game_restart.dart
deleted file mode 100644
index 48dfc34..0000000
--- a/lib/ui/widgets/home/button_game_restart.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/utils/game_utils.dart';
-
-class RestartGameButton extends StatelessWidget {
-  const RestartGameButton({super.key, required this.myProvider});
-
-  final Data myProvider;
-
-  @override
-  Widget build(BuildContext context) {
-    return TextButton(
-      child: const Image(
-        image: AssetImage('assets/icons/button_back.png'),
-        fit: BoxFit.fill,
-      ),
-      onPressed: () => GameUtils.quitAndDeleteCurrentGame(myProvider),
-    );
-  }
-}
diff --git a/lib/ui/widgets/home/button_game_resume.dart b/lib/ui/widgets/home/button_game_resume.dart
deleted file mode 100644
index 185c92f..0000000
--- a/lib/ui/widgets/home/button_game_resume.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:solitaire/ui/layout/parameters.dart';
-import 'package:solitaire/utils/game_utils.dart';
-
-class ResumeGameButton extends Parameters {
-  const ResumeGameButton({super.key, required super.myProvider});
-
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      margin: const EdgeInsets.all(Parameters.blockMargin),
-      padding: const EdgeInsets.all(Parameters.blockPadding),
-      child: Table(
-        defaultColumnWidth: const IntrinsicColumnWidth(),
-        children: [
-          TableRow(
-            children: [
-              Column(
-                children: [
-                  TextButton(
-                    child: Parameters.buildImageContainerWidget('button_delete_saved_game'),
-                    onPressed: () => GameUtils.deleteSavedGame(myProvider),
-                  ),
-                ],
-              ),
-              Column(
-                children: [
-                  TextButton(
-                    child: Parameters.buildImageContainerWidget('button_resume_game'),
-                    onPressed: () => GameUtils.resumeSavedGame(myProvider),
-                  ),
-                ],
-              ),
-              Parameters.buildDecorationImageWidget(),
-            ],
-          ),
-        ],
-      ),
-    );
-  }
-}
diff --git a/lib/ui/widgets/home/button_game_start_new.dart b/lib/ui/widgets/home/button_game_start_new.dart
deleted file mode 100644
index 2de0c55..0000000
--- a/lib/ui/widgets/home/button_game_start_new.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/ui/layout/parameters.dart';
-import 'package:solitaire/utils/game_utils.dart';
-
-class StartNewGameButton extends StatelessWidget {
-  const StartNewGameButton({super.key, required this.myProvider});
-
-  final Data myProvider;
-
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      margin: const EdgeInsets.all(Parameters.blockMargin),
-      padding: const EdgeInsets.all(Parameters.blockPadding),
-      child: Table(
-        defaultColumnWidth: const IntrinsicColumnWidth(),
-        children: [
-          TableRow(
-            children: [
-              Parameters.buildDecorationImageWidget(),
-              Column(
-                children: [
-                  TextButton(
-                    child: Parameters.buildImageContainerWidget('button_start'),
-                    onPressed: () => GameUtils.startNewGame(myProvider),
-                  ),
-                ],
-              ),
-              Parameters.buildDecorationImageWidget(),
-            ],
-          ),
-        ],
-      ),
-    );
-  }
-}
diff --git a/lib/ui/widgets/parameters.dart b/lib/ui/widgets/parameters.dart
new file mode 100644
index 0000000..11b080d
--- /dev/null
+++ b/lib/ui/widgets/parameters.dart
@@ -0,0 +1,115 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+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';
+
+class Parameters extends StatelessWidget {
+  const Parameters({super.key});
+
+  final double separatorHeight = 8.0;
+
+  @override
+  Widget build(BuildContext context) {
+    final List<Widget> lines = [];
+
+    // Game settings
+    for (String code in DefaultGameSettings.availableParameters) {
+      lines.add(Row(
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: buildParametersLine(
+          code: code,
+          isGlobal: false,
+        ),
+      ));
+
+      lines.add(SizedBox(height: separatorHeight));
+    }
+
+    lines.add(SizedBox(height: separatorHeight));
+    lines.add(const Expanded(child: StartNewGameButton()));
+    lines.add(SizedBox(height: separatorHeight));
+
+    // Global settings
+    for (String code in DefaultGlobalSettings.availableParameters) {
+      lines.add(Row(
+        mainAxisAlignment: MainAxisAlignment.spaceBetween,
+        children: buildParametersLine(
+          code: code,
+          isGlobal: true,
+        ),
+      ));
+
+      lines.add(SizedBox(height: separatorHeight));
+    }
+
+    return Column(
+      children: lines,
+    );
+  }
+
+  List<Widget> buildParametersLine({
+    required String code,
+    required bool isGlobal,
+  }) {
+    final List<Widget> parameterButtons = [];
+
+    final List<String> availableValues = isGlobal
+        ? DefaultGlobalSettings.getAvailableValues(code)
+        : DefaultGameSettings.getAvailableValues(code);
+
+    if (availableValues.length <= 1) {
+      return [];
+    }
+
+    for (String value in availableValues) {
+      final Widget parameterButton = BlocBuilder<GameSettingsCubit, GameSettingsState>(
+        builder: (BuildContext context, GameSettingsState gameSettingsState) {
+          return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
+            builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
+              final GameSettingsCubit gameSettingsCubit =
+                  BlocProvider.of<GameSettingsCubit>(context);
+              final GlobalSettingsCubit globalSettingsCubit =
+                  BlocProvider.of<GlobalSettingsCubit>(context);
+
+              final String currentValue = isGlobal
+                  ? globalSettingsCubit.getParameterValue(code)
+                  : gameSettingsCubit.getParameterValue(code);
+
+              final bool isActive = (value == currentValue);
+
+              final double displayWidth = MediaQuery.of(context).size.width;
+              final double itemWidth = displayWidth / availableValues.length - 26;
+
+              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,
+                ),
+                onPressed: () => isGlobal
+                    ? globalSettingsCubit.setParameterValue(code, value)
+                    : gameSettingsCubit.setParameterValue(code, value),
+              );
+            },
+          );
+        },
+      );
+
+      parameterButtons.add(parameterButton);
+    }
+
+    return parameterButtons;
+  }
+}
diff --git a/lib/utils/board_utils.dart b/lib/utils/board_utils.dart
deleted file mode 100644
index 349b05d..0000000
--- a/lib/utils/board_utils.dart
+++ /dev/null
@@ -1,120 +0,0 @@
-import 'dart:math';
-
-import 'package:solitaire/entities/tile.dart';
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/utils/tools.dart';
-
-class BoardUtils {
-  static printGrid(List cells) {
-    String textBoard = ' ';
-    String textHole = '·';
-    String textPeg = 'o';
-
-    printlog('');
-    printlog('-------');
-    for (int rowIndex = 0; rowIndex < cells.length; rowIndex++) {
-      String row = '';
-      for (int colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) {
-        String textCell = textBoard;
-        Tile? tile = cells[rowIndex][colIndex];
-        if (tile != null) {
-          textCell = tile.hasPeg ? textPeg : textHole;
-        }
-        row += textCell;
-      }
-      printlog(row);
-    }
-    printlog('-------');
-    printlog('');
-  }
-
-  static Board createBoardFromSavedState(Data myProvider, String savedBoard) {
-    Board board = [];
-    int boardSize = pow((savedBoard.length), 1 / 2).round();
-    myProvider.updateBoardSize(boardSize);
-
-    String textBoard = ' ';
-    String textPeg = 'o';
-
-    int index = 0;
-    for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) {
-      List<Tile?> row = [];
-      for (int colIndex = 0; colIndex < boardSize; colIndex++) {
-        String stringValue = savedBoard[index++];
-        if (stringValue == textBoard) {
-          row.add(null);
-        } else {
-          row.add(Tile(rowIndex, colIndex, (stringValue == textPeg)));
-        }
-      }
-      board.add(row);
-    }
-
-    return board;
-  }
-
-  static createNewBoard(Data myProvider) {
-    Map<String, List<String>> templates = {
-      'french': [
-        '  ooo  ',
-        ' ooooo ',
-        'ooo·ooo',
-        'ooooooo',
-        'ooooooo',
-        ' ooooo ',
-        '  ooo  ',
-      ],
-      'german': [
-        '   ooo   ',
-        '   ooo   ',
-        '   ooo   ',
-        'ooooooooo',
-        'oooo·oooo',
-        'ooooooooo',
-        '   ooo   ',
-        '   ooo   ',
-        '   ooo   ',
-      ],
-      'english': [
-        '  ooo  ',
-        '  ooo  ',
-        'ooooooo',
-        'ooo·ooo',
-        'ooooooo',
-        '  ooo  ',
-        '  ooo  ',
-      ],
-      'diamond': [
-        '    o    ',
-        '   ooo   ',
-        '  ooooo  ',
-        ' ooooooo ',
-        'oooo·oooo',
-        ' ooooooo ',
-        '  ooooo  ',
-        '   ooo   ',
-        '    o    ',
-      ]
-    };
-
-    List<String>? template = templates[myProvider.parameterLayout];
-
-    Board grid = [];
-    int row = 0;
-    template?.forEach((String line) {
-      List<Tile?> gridLine = [];
-      int col = 0;
-      line.split("").forEach((String tileCode) {
-        gridLine.add(tileCode == ' ' ? null : Tile(row, col, (tileCode == 'o')));
-        col++;
-      });
-      row++;
-      grid.add(gridLine);
-    });
-
-    printGrid(grid);
-
-    myProvider.resetGame();
-    myProvider.updateBoard(grid);
-  }
-}
diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart
deleted file mode 100644
index 69b0f4f..0000000
--- a/lib/utils/game_utils.dart
+++ /dev/null
@@ -1,180 +0,0 @@
-import 'package:solitaire/entities/tile.dart';
-import 'package:solitaire/provider/data.dart';
-import 'package:solitaire/utils/board_utils.dart';
-import 'package:solitaire/utils/tools.dart';
-
-class GameUtils {
-  static Future<void> quitGame(Data myProvider) async {
-    myProvider.updateGameIsRunning(false);
-  }
-
-  static Future<void> quitAndDeleteCurrentGame(Data myProvider) async {
-    quitGame(myProvider);
-    myProvider.resetCurrentSavedState();
-  }
-
-  static Future<void> startNewGame(Data myProvider) async {
-    printlog('Starting game');
-
-    BoardUtils.createNewBoard(myProvider);
-
-    myProvider.updateGameIsRunning(true);
-  }
-
-  static void deleteSavedGame(Data myProvider) {
-    myProvider.resetCurrentSavedState();
-  }
-
-  static void resumeSavedGame(Data myProvider) {
-    Map<String, dynamic> savedState = myProvider.getCurrentSavedState();
-    if (savedState.isNotEmpty) {
-      try {
-        myProvider.setParameterValue('layout', savedState['layout']);
-        myProvider.setParameterValue('skin', savedState['skin']);
-        myProvider.updateMovesCount(int.parse(savedState['movesCount']));
-        myProvider.updateBoard(
-            BoardUtils.createBoardFromSavedState(myProvider, savedState['boardValues']));
-
-        myProvider.updateGameIsRunning(true);
-      } catch (e) {
-        printlog('Failed to resume game. Will start new one instead.');
-        myProvider.resetCurrentSavedState();
-        myProvider.initParametersValues();
-        startNewGame(myProvider);
-      }
-    } else {
-      myProvider.resetCurrentSavedState();
-      myProvider.initParametersValues();
-      startNewGame(myProvider);
-    }
-  }
-
-  static bool isMoveAllowed(Data myProvider, List<int> source, List<int> target) {
-    // printlog('(test) Pick from ' + source.toString() + ' and drop on ' + target.toString());
-    final Board board = myProvider.board;
-    final int sourceCol = source[0];
-    final int sourceRow = source[1];
-    final int targetCol = target[0];
-    final int targetRow = target[1];
-
-    // ensure source and target are inside range
-    if (sourceRow < 0 ||
-        sourceRow > (myProvider.boardSize - 1) ||
-        sourceCol < 0 ||
-        sourceCol > (myProvider.boardSize - 1)) {
-      // printlog('move forbidden: source is out of board');
-      return false;
-    }
-    if (targetRow < 0 ||
-        targetRow > (myProvider.boardSize - 1) ||
-        targetCol < 0 ||
-        targetCol > (myProvider.boardSize - 1)) {
-      // printlog('move forbidden: target is out of board');
-      return false;
-    }
-
-    // ensure source exists and has a peg
-    if (board[sourceRow][sourceCol] == null || board[sourceRow][sourceCol]?.hasPeg == false) {
-      // printlog('move forbidden: source peg does not exist');
-      return false;
-    }
-
-    // ensure target exists and is empty
-    if (board[targetRow][targetCol] == null || board[targetRow][targetCol]?.hasPeg == true) {
-      // printlog('move forbidden: target does not exist or already with a peg');
-      return false;
-    }
-
-    // ensure source and target are in the same line/column
-    if ((targetCol != sourceCol) && (targetRow != sourceRow)) {
-      // printlog('move forbidden: source and target are not in the same line or column');
-      return false;
-    }
-
-    // ensure source and target are separated by exactly one tile
-    if (((targetCol == sourceCol) && ((targetRow - sourceRow).abs() != 2)) ||
-        ((targetRow == sourceRow) && ((targetCol - sourceCol).abs() != 2))) {
-      // printlog('move forbidden: source and target must be separated by exactly one tile');
-      return false;
-    }
-
-    // ensure middle tile exists and has a peg
-    final int middleRow = (sourceRow + ((targetRow - sourceRow) / 2)).round();
-    final int middleCol = (sourceCol + ((targetCol - sourceCol) / 2)).round();
-    if (board[middleRow][middleCol] == null || board[middleRow][middleCol]?.hasPeg == false) {
-      // printlog('move forbidden: tile between source and target does not contain a peg');
-      return false;
-    }
-
-    // ok, move is allowed
-    return true;
-  }
-
-  static void move(Data myProvider, List<int> source, List<int> target) {
-    printlog('Move from $source to $target');
-    final int sourceCol = source[0];
-    final int sourceRow = source[1];
-    final int targetCol = target[0];
-    final int targetRow = target[1];
-
-    final int middleRow = (sourceRow + ((targetRow - sourceRow) / 2)).round();
-    final int middleCol = (sourceCol + ((targetCol - sourceCol) / 2)).round();
-
-    // remove peg from source
-    myProvider.updatePegValue(sourceRow, sourceCol, false);
-    // put peg in target
-    myProvider.updatePegValue(targetRow, targetCol, true);
-    // remove peg from middle tile
-    myProvider.updatePegValue(middleRow, middleCol, false);
-
-    // increment moves count
-    myProvider.incrementMovesCount();
-    // update remaining pegs count
-    myProvider.updateRemainingPegsCount(GameUtils.countRemainingPegs(myProvider));
-    // update allowed moves count
-    myProvider.updateAllowedMovesCount(GameUtils.countAllowedMoves(myProvider));
-  }
-
-  static List<Tile> listRemainingPegs(Data myProvider) {
-    List<Tile> pegs = [];
-
-    Board board = myProvider.board;
-    for (int rowIndex = 0; rowIndex < board.length; rowIndex++) {
-      for (int colIndex = 0; colIndex < board[rowIndex].length; colIndex++) {
-        Tile? tile = board[rowIndex][colIndex];
-        if (tile != null && tile.hasPeg == true) {
-          pegs.add(tile);
-        }
-      }
-    }
-
-    return pegs;
-  }
-
-  static int countRemainingPegs(Data myProvider) {
-    return GameUtils.listRemainingPegs(myProvider).length;
-  }
-
-  static int countAllowedMoves(Data myProvider) {
-    int allowedMovesCount = 0;
-    List<Tile> pegs = GameUtils.listRemainingPegs(myProvider);
-    for (Tile tile in pegs) {
-      final int row = tile.currentRow;
-      final int col = tile.currentCol;
-      final List<int> source = [col, row];
-      final List<List<int>> targets = [
-        [col - 2, row],
-        [col + 2, row],
-        [col, row - 2],
-        [col, row + 2],
-      ];
-      for (List<int> target in targets) {
-        if (GameUtils.isMoveAllowed(myProvider, source, target)) {
-          allowedMovesCount++;
-        }
-      }
-    }
-
-    return allowedMovesCount;
-  }
-}
diff --git a/pubspec.lock b/pubspec.lock
index 12d429b..bdba0ef 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,10 +5,10 @@ packages:
     dependency: transitive
     description:
       name: args
-      sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
+      sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
       url: "https://pub.dev"
     source: hosted
-    version: "2.4.2"
+    version: "2.5.0"
   async:
     dependency: transitive
     description:
@@ -21,10 +21,10 @@ packages:
     dependency: transitive
     description:
       name: bloc
-      sha256: f53a110e3b48dcd78136c10daa5d51512443cea5e1348c9d80a320095fa2db9e
+      sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
       url: "https://pub.dev"
     source: hosted
-    version: "8.1.3"
+    version: "8.1.4"
   characters:
     dependency: transitive
     description:
@@ -61,10 +61,10 @@ packages:
     dependency: "direct main"
     description:
       name: easy_localization
-      sha256: c145aeb6584aedc7c862ab8c737c3277788f47488bfdf9bae0fe112bd0a4789c
+      sha256: fa59bcdbbb911a764aa6acf96bbb6fa7a5cf8234354fc45ec1a43a0349ef0201
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.5"
+    version: "3.0.7"
   easy_logger:
     dependency: transitive
     description:
@@ -106,18 +106,18 @@ packages:
     dependency: "direct main"
     description:
       name: flutter_bloc
-      sha256: "87325da1ac757fcc4813e6b34ed5dd61169973871fdf181d6c2109dd6935ece1"
+      sha256: f0ecf6e6eb955193ca60af2d5ca39565a86b8a142452c5b24d96fb477428f4d2
       url: "https://pub.dev"
     source: hosted
-    version: "8.1.4"
+    version: "8.1.5"
   flutter_lints:
     dependency: "direct dev"
     description:
       name: flutter_lints
-      sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
+      sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.1"
+    version: "4.0.0"
   flutter_localizations:
     dependency: transitive
     description: flutter
@@ -140,10 +140,10 @@ packages:
     dependency: transitive
     description:
       name: http
-      sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
+      sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
       url: "https://pub.dev"
     source: hosted
-    version: "1.2.0"
+    version: "1.2.1"
   http_parser:
     dependency: transitive
     description:
@@ -156,10 +156,10 @@ packages:
     dependency: "direct main"
     description:
       name: hydrated_bloc
-      sha256: "00a2099680162e74b5a836b8a7f446e478520a9cae9f6032e028ad8129f4432d"
+      sha256: af35b357739fe41728df10bec03aad422cdc725a1e702e03af9d2a41ea05160c
       url: "https://pub.dev"
     source: hosted
-    version: "9.1.4"
+    version: "9.1.5"
   intl:
     dependency: transitive
     description:
@@ -172,10 +172,10 @@ packages:
     dependency: transitive
     description:
       name: lints
-      sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
+      sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.0"
+    version: "4.0.0"
   material_color_utilities:
     dependency: transitive
     description:
@@ -200,32 +200,24 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.0"
-  overlay_support:
-    dependency: "direct main"
-    description:
-      name: overlay_support
-      sha256: fc39389bfd94e6985e1e13b2a88a125fc4027608485d2d4e2847afe1b2bb339c
-      url: "https://pub.dev"
-    source: hosted
-    version: "2.1.0"
   package_info_plus:
     dependency: "direct main"
     description:
       name: package_info_plus
-      sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79"
+      sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0
       url: "https://pub.dev"
     source: hosted
-    version: "5.0.1"
+    version: "8.0.0"
   package_info_plus_platform_interface:
     dependency: transitive
     description:
       name: package_info_plus_platform_interface
-      sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
+      sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e
       url: "https://pub.dev"
     source: hosted
-    version: "2.0.1"
+    version: "3.0.0"
   path:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: path
       sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
@@ -236,26 +228,26 @@ packages:
     dependency: "direct main"
     description:
       name: path_provider
-      sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
+      sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.2"
+    version: "2.1.3"
   path_provider_android:
     dependency: transitive
     description:
       name: path_provider_android
-      sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
+      sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.2"
+    version: "2.2.4"
   path_provider_foundation:
     dependency: transitive
     description:
       name: path_provider_foundation
-      sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
+      sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.2"
+    version: "2.4.0"
   path_provider_linux:
     dependency: transitive
     description:
@@ -297,7 +289,7 @@ packages:
     source: hosted
     version: "2.1.8"
   provider:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: provider
       sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
@@ -305,29 +297,29 @@ packages:
     source: hosted
     version: "6.1.2"
   shared_preferences:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: shared_preferences
-      sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
+      sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.2"
+    version: "2.2.3"
   shared_preferences_android:
     dependency: transitive
     description:
       name: shared_preferences_android
-      sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
+      sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.1"
+    version: "2.2.2"
   shared_preferences_foundation:
     dependency: transitive
     description:
       name: shared_preferences_foundation
-      sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
+      sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.5"
+    version: "2.4.0"
   shared_preferences_linux:
     dependency: transitive
     description:
@@ -348,10 +340,10 @@ packages:
     dependency: transitive
     description:
       name: shared_preferences_web
-      sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
+      sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
       url: "https://pub.dev"
     source: hosted
-    version: "2.2.2"
+    version: "2.3.0"
   shared_preferences_windows:
     dependency: transitive
     description:
@@ -425,18 +417,18 @@ packages:
     dependency: transitive
     description:
       name: web
-      sha256: "4188706108906f002b3a293509234588823c8c979dc83304e229ff400c996b05"
+      sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
       url: "https://pub.dev"
     source: hosted
-    version: "0.4.2"
+    version: "0.5.1"
   win32:
     dependency: transitive
     description:
       name: win32
-      sha256: "8cb58b45c47dcb42ab3651533626161d6b67a2921917d8d429791f76972b3480"
+      sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
       url: "https://pub.dev"
     source: hosted
-    version: "5.3.0"
+    version: "5.5.0"
   xdg_directories:
     dependency: transitive
     description:
@@ -447,4 +439,4 @@ packages:
     version: "1.0.4"
 sdks:
   dart: ">=3.3.0 <4.0.0"
-  flutter: ">=3.16.0"
+  flutter: ">=3.19.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 5c4cd59..5c63879 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,12 @@
 name: solitaire
 description: Solitaire Game
 
-publish_to: 'none'
-version: 0.0.17+17
+publish_to: "none"
+
+version: 0.0.18+18
 
 environment:
-  sdk: '^3.0.0'
+  sdk: "^3.0.0"
 
 dependencies:
   flutter:
@@ -16,16 +17,12 @@ dependencies:
   flutter_bloc: ^8.1.1
   hive: ^2.2.3
   hydrated_bloc: ^9.0.0
-  overlay_support: ^2.1.0
-  provider: ^6.0.5
-  shared_preferences: ^2.2.1
-  package_info_plus: ^5.0.1
-  path: ^1.9.0
+  package_info_plus: ^8.0.0
   path_provider: ^2.0.11
   unicons: ^2.1.1
 
 dev_dependencies:
-  flutter_lints: ^3.0.1
+  flutter_lints: ^4.0.0
 
 flutter:
   uses-material-design: true
@@ -45,4 +42,3 @@ flutter:
           weight: 400
         - asset: assets/fonts/Nunito-Light.ttf
           weight: 300
-
-- 
GitLab