From 01a604bcd0af615bc34832db8ed3065979a9271c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Wed, 23 Oct 2024 14:57:08 +0200
Subject: [PATCH] Normalize Activity application architecture

---
 assets/translations/en.json                   |  16 +-
 assets/translations/fr.json                   |  16 +-
 assets/ui/button_back.png                     | Bin 0 -> 2422 bytes
 assets/ui/button_delete_saved_game.png        | Bin 0 -> 7834 bytes
 assets/ui/button_resume_game.png              | Bin 0 -> 3434 bytes
 assets/ui/button_start.png                    | Bin 0 -> 3058 bytes
 lib/common/config/activity_page.dart          |  86 ++++++++
 lib/common/config/screen.dart                 |  55 +++++
 lib/common/cubit/nav/nav_cubit_pages.dart     |  33 +++
 lib/common/cubit/nav/nav_cubit_screens.dart   |  37 ++++
 lib/common/ui/nav/bottom_nav_bar.dart         |  46 ++++
 lib/common/ui/nav/global_app_bar.dart         |  86 ++++++++
 .../ui/pages/api.dart}                        |  10 +-
 .../ui/pages/camera.dart}                     |   6 +-
 lib/common/ui/pages/demo.dart                 | 195 +++++++++++++++++
 .../ui/pages/game.dart}                       |  37 ++--
 .../ui/pages/graph.dart}                      |   8 +-
 lib/common/ui/pages/parameters.dart           | 148 +++++++++++++
 .../ui/parameters/parameter_painter.dart      | 196 +++++++++++++++++
 .../ui/parameters/parameter_widget.dart       | 162 ++++++++++++++
 lib/common/ui/screens/about.dart              |  38 ++++
 lib/common/ui/screens/activity.dart           |  18 ++
 lib/common/ui/screens/settings.dart           |  26 +++
 .../ui/settings}/settings_form.dart           |   9 +-
 lib/config/application_config.dart            |   3 +
 lib/config/default_activity_settings.dart     |  52 +++++
 lib/config/default_global_settings.dart       |  28 +++
 lib/config/menu.dart                          |  80 -------
 lib/cubit/activity/activity_cubit.dart        |  82 ++++++++
 lib/cubit/activity/activity_state.dart        |  15 ++
 lib/cubit/{ => activity}/api_cubit.dart       |   0
 lib/cubit/{ => activity}/api_state.dart       |   0
 lib/cubit/{ => activity}/data_cubit.dart      |   0
 lib/cubit/{ => activity}/data_state.dart      |   0
 lib/cubit/bottom_nav_cubit.dart               |  31 ---
 lib/cubit/game_cubit.dart                     |  34 ---
 lib/cubit/game_state.dart                     |  15 --
 .../settings/settings_activity_cubit.dart     |  72 +++++++
 .../settings/settings_activity_state.dart     |  15 ++
 lib/cubit/{ => settings}/settings_cubit.dart  |   0
 lib/cubit/settings/settings_global_cubit.dart |  59 ++++++
 lib/cubit/settings/settings_global_state.dart |  15 ++
 lib/cubit/{ => settings}/settings_state.dart  |   0
 lib/main.dart                                 | 110 ++++++----
 .../game.dart => activity/activity.dart}      |  52 +++--
 lib/models/{game => activity}/game_board.dart |  12 +-
 lib/models/{game => activity}/game_cell.dart  |   0
 lib/models/game/game_settings.dart            |  46 ----
 lib/models/settings/settings_activity.dart    |  59 ++++++
 lib/models/settings/settings_global.dart      |  42 ++++
 lib/ui/screens/about_page.dart                |  37 ----
 lib/ui/screens/demo_page.dart                 | 198 ------------------
 lib/ui/screens/settings_page.dart             |  23 --
 lib/ui/skeleton.dart                          |  55 +++--
 .../actions/button_delete_saved_game.dart     |  22 ++
 lib/ui/widgets/actions/button_game_quit.dart  |  25 +++
 .../actions/button_game_start_new.dart        |  38 ++++
 .../actions/button_resume_saved_game.dart     |  25 +++
 lib/ui/widgets/app_bar.dart                   |  20 --
 .../{header_app.dart => custom_title.dart}    |  10 +-
 lib/ui/widgets/game/game_board.dart           |  48 ++---
 lib/ui/widgets/game/game_score.dart           |  18 +-
 lib/ui/widgets/game/game_settings.dart        |  12 --
 lib/ui/widgets/theme_card.dart                |  43 ----
 pubspec.lock                                  |  16 +-
 pubspec.yaml                                  |   4 +-
 resources/build_resources.sh                  |   1 +
 resources/ui/build_ui_resources.sh            | 144 +++++++++++++
 resources/ui/images/button_back.svg           |  48 +----
 .../ui/images/button_delete_saved_game.svg    |  40 +---
 resources/ui/images/button_resume_game.svg    |  54 +----
 resources/ui/images/button_start.svg          |  48 +----
 72 files changed, 2063 insertions(+), 916 deletions(-)
 create mode 100644 assets/ui/button_back.png
 create mode 100644 assets/ui/button_delete_saved_game.png
 create mode 100644 assets/ui/button_resume_game.png
 create mode 100644 assets/ui/button_start.png
 create mode 100644 lib/common/config/activity_page.dart
 create mode 100644 lib/common/config/screen.dart
 create mode 100644 lib/common/cubit/nav/nav_cubit_pages.dart
 create mode 100644 lib/common/cubit/nav/nav_cubit_screens.dart
 create mode 100644 lib/common/ui/nav/bottom_nav_bar.dart
 create mode 100644 lib/common/ui/nav/global_app_bar.dart
 rename lib/{ui/screens/api_page.dart => common/ui/pages/api.dart} (82%)
 rename lib/{ui/screens/camera_page.dart => common/ui/pages/camera.dart} (82%)
 create mode 100644 lib/common/ui/pages/demo.dart
 rename lib/{ui/screens/game_page.dart => common/ui/pages/game.dart} (57%)
 rename lib/{ui/screens/graph_page.dart => common/ui/pages/graph.dart} (92%)
 create mode 100644 lib/common/ui/pages/parameters.dart
 create mode 100644 lib/common/ui/parameters/parameter_painter.dart
 create mode 100644 lib/common/ui/parameters/parameter_widget.dart
 create mode 100644 lib/common/ui/screens/about.dart
 create mode 100644 lib/common/ui/screens/activity.dart
 create mode 100644 lib/common/ui/screens/settings.dart
 rename lib/{ui/widgets => common/ui/settings}/settings_form.dart (95%)
 create mode 100644 lib/config/application_config.dart
 create mode 100644 lib/config/default_activity_settings.dart
 create mode 100644 lib/config/default_global_settings.dart
 delete mode 100644 lib/config/menu.dart
 create mode 100644 lib/cubit/activity/activity_cubit.dart
 create mode 100644 lib/cubit/activity/activity_state.dart
 rename lib/cubit/{ => activity}/api_cubit.dart (100%)
 rename lib/cubit/{ => activity}/api_state.dart (100%)
 rename lib/cubit/{ => activity}/data_cubit.dart (100%)
 rename lib/cubit/{ => activity}/data_state.dart (100%)
 delete mode 100644 lib/cubit/bottom_nav_cubit.dart
 delete mode 100644 lib/cubit/game_cubit.dart
 delete mode 100644 lib/cubit/game_state.dart
 create mode 100644 lib/cubit/settings/settings_activity_cubit.dart
 create mode 100644 lib/cubit/settings/settings_activity_state.dart
 rename lib/cubit/{ => settings}/settings_cubit.dart (100%)
 create mode 100644 lib/cubit/settings/settings_global_cubit.dart
 create mode 100644 lib/cubit/settings/settings_global_state.dart
 rename lib/cubit/{ => settings}/settings_state.dart (100%)
 rename lib/models/{game/game.dart => activity/activity.dart} (50%)
 rename lib/models/{game => activity}/game_board.dart (76%)
 rename lib/models/{game => activity}/game_cell.dart (100%)
 delete mode 100644 lib/models/game/game_settings.dart
 create mode 100644 lib/models/settings/settings_activity.dart
 create mode 100644 lib/models/settings/settings_global.dart
 delete mode 100644 lib/ui/screens/about_page.dart
 delete mode 100644 lib/ui/screens/demo_page.dart
 delete mode 100644 lib/ui/screens/settings_page.dart
 create mode 100644 lib/ui/widgets/actions/button_delete_saved_game.dart
 create mode 100644 lib/ui/widgets/actions/button_game_quit.dart
 create mode 100644 lib/ui/widgets/actions/button_game_start_new.dart
 create mode 100644 lib/ui/widgets/actions/button_resume_saved_game.dart
 delete mode 100644 lib/ui/widgets/app_bar.dart
 rename lib/ui/widgets/{header_app.dart => custom_title.dart} (85%)
 delete mode 100644 lib/ui/widgets/game/game_settings.dart
 delete mode 100644 lib/ui/widgets/theme_card.dart
 create mode 100755 resources/ui/build_ui_resources.sh

diff --git a/assets/translations/en.json b/assets/translations/en.json
index 4f59762..0b5c2c0 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -1,13 +1,15 @@
 {
   "app_name": "Sandbox App",
 
-  "bottom_nav_sample": "Sample",
-  "bottom_nav_camera": "Camera",
-  "bottom_nav_api": "API",
-  "bottom_nav_chart": "Graph",
-  "bottom_nav_game": "Game",
-  "bottom_nav_settings": "Settings",
-  "bottom_nav_about": "About",
+  "page_home": "Home",
+  "page_demo": "Demo",
+  "page_camera": "Camera",
+  "page_api": "API",
+  "page_graph": "Graph",
+  "page_game": "Game",
+
+  "screen_settings": "Settings",
+  "screen_about": "About",
 
   "api_page_title": "API",
 
diff --git a/assets/translations/fr.json b/assets/translations/fr.json
index aa559e2..81fdba3 100644
--- a/assets/translations/fr.json
+++ b/assets/translations/fr.json
@@ -1,13 +1,15 @@
 {
   "app_name": "App de test",
 
-  "bottom_nav_sample": "Démo",
-  "bottom_nav_camera": "Caméra",
-  "bottom_nav_api": "API",
-  "bottom_nav_chart": "Graph",
-  "bottom_nav_game": "Jeu",
-  "bottom_nav_settings": "Paramètres",
-  "bottom_nav_about": "À propos",
+  "page_home": "Accueil",
+  "page_demo": "Démo",
+  "page_camera": "Caméra",
+  "page_api": "API",
+  "page_graph": "Graph",
+  "page_game": "Jeu",
+
+  "screen_settings": "Paramètres",
+  "screen_about": "À propos",
 
   "api_page_title": "API",
 
diff --git a/assets/ui/button_back.png b/assets/ui/button_back.png
new file mode 100644
index 0000000000000000000000000000000000000000..51d7a01d171f7d7f047ecf9dee2d7ceee23b310d
GIT binary patch
literal 2422
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
BcJ%-N

literal 0
HcmV?d00001

diff --git a/assets/ui/button_delete_saved_game.png b/assets/ui/button_delete_saved_game.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ca5b749c208c4b7eac2a4b141a1bd918d7cb98f
GIT binary patch
literal 7834
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
HN@xNA9?owD

literal 0
HcmV?d00001

diff --git a/assets/ui/button_resume_game.png b/assets/ui/button_resume_game.png
new file mode 100644
index 0000000000000000000000000000000000000000..2fe433b7d18a39880a14e3f0af18cb75c4ccbaed
GIT binary patch
literal 3434
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
J);T3K0RaB++}HpB

literal 0
HcmV?d00001

diff --git a/assets/ui/button_start.png b/assets/ui/button_start.png
new file mode 100644
index 0000000000000000000000000000000000000000..23c7a4f670de19ffac455d6c510c3c53653a048b
GIT binary patch
literal 3058
zcmeAS@N?(olHy`uVBq!ia0y~yU^oE69Bd2>3_*8t*cliYI14-?iy0W?oEaG8oERJS
zYjH3zFi4iTMwA5Sr<If^7Ns(jmzV2h=4BTrCl;jY<rk&TerF@az`$Ma>EaktaqI2e
z+8&Xovd7n7n=Z8D_S~loi}!Q{T++~2H56=#x_p5nD=BDi#DlW3_d4ymOSfKWNsz8u
zx^1hHs+pQs^t-&YZ+)9wR_e3z>a$N=)ga^I_@H9)^lHbQ)>C#jKYlRp+?&(}kE><n
zW##i~?e0IBJ>kRsv)?y=KJ%`;ZoiG9i`=nQv+SAJ7<w2Pk{J$2Fc{!wD)gSa-utg{
zgQa)(jE@WQ-toOi3l1=sdQ+c&z2vp)@B94Ert0qQ>+US(YPfJF!ZBd`v>T53+jaNd
zacf>CZGUq2@^4XkTGQkhehdHSv%YbBpVg1>oBNz4f_H3)h+=4(xN7%Xg>n_af7*Y~
zHzj4Oh)a00HvBzle~0h=OOeCxf6Wmy`yUdq%Vs`z?^1>Xd~enI57nRSY=71fIw?G^
zj#pgfw;023#cz!35C6B!zpfNIdB=+z(-~MwvVCVU7W|Deh^pikm;cSy;F!31z3iFK
zl1vUNa+?l6J9N<Xqg@LF!=F!Q`%g6Wvz0s+{Js8z=^+M&o7Vr`*Sw5mI`H*cfQeb7
z1B1h~bN`RM(P4h@BPqcA-?j3pvkFa&3^VsJ|GB}=up@7~qsIB!zo$!ca4@XkXn4)s
zxFOQTgTWz`;m)GFRk~8r&Jhd_feb?Lt{r-|sZLdtnS&RsZrXypzjJPxGOXZgxUGL{
z^~+->Oe_puOa-ZHl>}BwIZgnX;IinDpxON5dkM+`3=5PP)=4u9uI>TrIq)>9HP1&S
zhGBsgLtnK}uufVCzj6vl(e&)=y8`{*N->169{Bn(;mD<xvCIvt7*y80e72i4@v~nO
zJII!uWx2DitYdTtWr&%-u#A^Mi}}Ge-`60ehZtf$S?T8VsZC*cu#($bXJ?kEU~#5F
zl%&cWh6kPZ@0ACgiQDFyA-M7#+up6O7yY=-smZY9$zgSS;l45%JJo&rGuBR6Q}#E}
z@y4F%3z!^EF<88MDVTJ0nsd^XJE5PhuJc}<ueyO@f)K+xt8=B@_WSmD^Hgn#QsdaQ
zB9^&9onc4OKmA{S(r)fE%Uw{$%P^1OLDuJaYKAYv*PkrYNxEgqP{G`=xceJ()8`t4
zBEOhjx3(^u?aXP+u!N;y^|o(%f%}TuB_gCIuPd7?zV;8>Lbiq}3<aV0f2`Dq+T^$`
z`J&<SGT#l13aJb+SKsA{l<QTv>Ioc5%iVB8%KZRHSZ412g1|i=p2ZoKeB*kVb^Y(5
zXAVt#4D(hzJ!5Hj|CZV>_oc7Ix3ZRG+ilHe_~5g<Z%aq!{(9$a&zt|AQ*v_RXPB3n
zd$-WA?B3~1SJydDTy>k%o}psVxpjFPzkI#>=-DQzm&<Nurha5#U}#X!%6U6sV_B`&
zSCFsPeCMlGTK1=`H|4le_VUdug&7zQ2z$ov=9_((k%7VH;?i5CD?_%v_VYELr>7G;
zkDr0zK_{PS@NPDSR>p#@nf{Y^ygnJ8x;iw6TQs_yk%6IN(K~M2MVq$8ow`-JVo4GQ
z*uvcRYePNEwk@^2o^_pJLh4oXd1Czb-fyKCL|7l3iaPp3J?u2wAva(1V@wPT6-wL7
zY+FEyjiX`pvu%DKD~?)ky1Fh}7!>JW85kJmWjvo4ob)QV=;}JtyLXnip8d_hz+kgF
zbj`hA6D5q_tNzToZk)Uw<dm@8Wm%%;|5nTbna19*x=k$WI>Q13hIQNIr)(_Cy_R|O
zS~*DXMC-G8SMKa6+4?$R%O^1g1_u8tbz%2zeQj7&VGrV!1f06HwNh!e_Yp<~_NP9Z
zXKN(CjWSmQIW}syoMHOXkgeIv!weOoDwRRrEy}(=>8h4d*lsok*Dd=WZmG!lSaowA
zKi`t-P74MNwdG}h-^P2HpUrC)>+NM^VEEvYem-8nJMOQ;w#>4-=dLe{<NwLZ(0cXC
zHO=_7N=ffNd{UHTn9#Ge>o05nKU)?Ch6gk6WR~6kHB;vDn>X!`x5oXcU}Jc(D(dK>
z(9$3s!RsZ(YzzzzQ6-C(-u-@_{oL*Jm454(8NMv7%Ff?B<4^W~JwgA{ELnyH>#wwS
z+b&8vTsQxk)*4q(6*6(NOO4~#GQ$Nb&z7%u4QFOxNC`P-V*US$)*9VU%mQZe-q+<%
zNc#5exw=ny`BDCPAK4ig@772&FeoIuE8OS(@|5F<pvK*z`?mj{`9H3!nV6<n&hU;Q
z^K#mJ{jVo_*E=#ED7X6bQ8Mt)9ku%FiY3MQt4cW-9Ku5tPdzRT@|m%r__OmW0UPED
zrE<2HFXH#ONcLGbMBOTTko<A){XgEbthUsC`DqYu{;PY=N@r$=uq!uiDW>iHFfFIp
zZM*oibvrztT;Vokm=HMk?Jfne{h#*j$eb3k-eunPlGigqg>F;0QYD*5*g5ZykC#+y
z-iyeu_vrI;|Hj}TxVL_b>z)7Y=BeCuw#k7E3aXw~60d!d45l3yR$y>Y+$pWzZu^b@
zrJ3KixpBrC!8e&3WTqI)lpkW++4eYV*Uvl+so4`=zF~CWd+Bg_`J;*U`BQRV-7Y+~
znAyS0>h49=Q{nF><T|>sa~m-zsQ%ow>`a#mgU9kec55GYACtP3{`X|v2^j_tEzj#q
z>JH5cVes&Lw<t$aZCh<!U|B}mngjU<*%>@lqJ4j!Dy~xqGCj2ZAUgwRNcoQ`JHD6a
zpZHe$&(7C;*-zUa3=fh`x0iMu*S;sXup{Ja>$M}6|L5JxPUW;`_~8?KckkC$#m(U-
zw(eBT(R&>pWazN$0dvFoBk%MW0)!aqdnLb||K`SUqLAUvtWE2et@)Wzug~yAgCVDY
zogtO+#+K!tJ~ct>W)&Ia<Z-_|b|i+|jv*z0eYU;u#pmXy%g)(PJUh#X;Ryr7xhY#+
zY8}_jDq1d|b&5g3kRi{v@=8qBDTW0S3_^Ny%VNZPLhh~&`oP#QYt!T4y0x0j4Jr&4
zrcalye=lY}{i;WJ@U>Hq7(<)+8RV{tA3HO7-LgG;CdOs6Umav`5ZUtDqkG1$DJ`Z?
zJ4)>rvNuf0J~hcVGMo3swVK~^>TMg@8<srri=4b>*_;`huIcCSsk~sAaLKa%kMQbL
z>*x7bN|JRL*&CKH7G#~`x8Lo!?SXvpD{dBPhDmG(rk`FQx<-@Pp^dR1`;_u?kI?uR
z7nRatE}vc4A_<aze|o|G4a?>{nv}7|f}wrM8ck{5#*WZwpoRb=Tf-8D7Z&QNzB^B^
z)EAkicV2x5!vqmfNZgzCN$cmbHLYhKvWPKEVtcUH+34DowR68M|5whb#h~)G{(bhe
zjmz#Vs`8E0Ww^9MBYM;O&*yI+j2G$&W8+jWXSljYPh{n;xdBWKS@+hzJjUE2$PmI^
z7rkiNoW|4(5)3OelNmlZ)-E)Q$mvzCU|1l<a6ELzCN>6!f~!UupdeRb=$utl;P%zP
ziH#xhuc8k3J*lo^Y65x;0dM&(c=$>(gs?0){r>a<Lxv^mm&HWYYCAG9EM?$$@$6o}
zm04a53=XCYQ7JKOy^IGYr(XDZIh%`<mqCNAVdFi%{~3pv7`hk}t~@_wl)=OBzyG|-
zEAA^(7!`u~UL4D@zcR)2?jLQ_RE86OWF5@AHrv!DZvMN{ejcbz)8`O6d4*<jDr3Pk
zBXup-nQJuL&$c#qKdR+mWccyK@<7z&&RInc=Bu5Jlbd(`xDn2fk@$JvmNxsOcN^r3
z)Qc}})MqR>_wZc5U*>8}<5b??k_|@;HG)hRZO?z~`Qd!#u8$^{r))G~uqbOg`0by>
z)JuiwTbYH$CA`@k9{CBFz2DGWqtf}IUf@EnW=w>RDMM%bqfHeD><;N{bH4l2p5?#t
z^Swz~r!3MLc9fXU2wZ!!ye0CRdUfw-&ivm?-Y!1Zr?Y%fj=hEbjPPx5tn}2*dE#rp
iBDZiK|9|(N;ehnnGdx!%I~W)k7(8A5T-G@yGywo2(N(Yj

literal 0
HcmV?d00001

diff --git a/lib/common/config/activity_page.dart b/lib/common/config/activity_page.dart
new file mode 100644
index 0000000..847186e
--- /dev/null
+++ b/lib/common/config/activity_page.dart
@@ -0,0 +1,86 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+import 'package:random/common/ui/pages/api.dart';
+import 'package:random/common/ui/pages/camera.dart';
+import 'package:random/common/ui/pages/demo.dart';
+import 'package:random/common/ui/pages/graph.dart';
+
+import 'package:random/common/ui/pages/game.dart';
+import 'package:random/common/ui/pages/parameters.dart';
+
+class ActivityPageItem {
+  final String code;
+  final Icon icon;
+  final Widget page;
+
+  const ActivityPageItem({
+    required this.code,
+    required this.icon,
+    required this.page,
+  });
+}
+
+class ActivityPage {
+  static const bool displayBottomNavBar = true;
+
+  static const indexHome = 0;
+  static const pageHome = ActivityPageItem(
+    code: 'page_home',
+    icon: Icon(UniconsLine.home),
+    page: PageParameters(),
+  );
+
+  static const indexDemo = 1;
+  static const pageDemo = ActivityPageItem(
+    code: 'page_demo',
+    icon: Icon(UniconsLine.eye),
+    page: PageDemo(),
+  );
+
+  static const indexGame = 2;
+  static const pageGame = ActivityPageItem(
+    code: 'page_game',
+    icon: Icon(UniconsLine.star),
+    page: PageGame(),
+  );
+
+  static const indexCamera = 3;
+  static const pageCamera = ActivityPageItem(
+    code: 'page_camera',
+    icon: Icon(UniconsLine.camera),
+    page: PageCamera(),
+  );
+
+  static const indexGraph = 4;
+  static const pageGraph = ActivityPageItem(
+    code: 'page_graph',
+    icon: Icon(UniconsLine.pen),
+    page: PageGraph(),
+  );
+
+  static const indexApi = 5;
+  static const pageApi = ActivityPageItem(
+    code: 'page_api',
+    icon: Icon(UniconsLine.link),
+    page: PageApi(),
+  );
+
+  static const Map<int, ActivityPageItem> items = {
+    indexHome: pageHome,
+    indexDemo: pageDemo,
+    indexGame: pageGame,
+    indexCamera: pageCamera,
+    indexGraph: pageGraph,
+    indexApi: pageApi,
+  };
+
+  static int defaultPageIndex = indexDemo;
+
+  static bool isIndexAllowed(int pageIndex) {
+    return items.keys.contains(pageIndex);
+  }
+
+  static Widget getWidget(int pageIndex) {
+    return items[pageIndex]?.page ?? pageHome.page;
+  }
+}
diff --git a/lib/common/config/screen.dart b/lib/common/config/screen.dart
new file mode 100644
index 0000000..2a828ee
--- /dev/null
+++ b/lib/common/config/screen.dart
@@ -0,0 +1,55 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/ui/screens/about.dart';
+import 'package:random/common/ui/screens/activity.dart';
+import 'package:random/common/ui/screens/settings.dart';
+
+class ScreenItem {
+  final String code;
+  final Icon icon;
+  final Widget screen;
+
+  const ScreenItem({
+    required this.code,
+    required this.icon,
+    required this.screen,
+  });
+}
+
+class Screen {
+  static const indexActivity = 0;
+  static const screenActivity = ScreenItem(
+    code: 'screen_activity',
+    icon: Icon(UniconsLine.home),
+    screen: ScreenActivity(),
+  );
+
+  static const indexSettings = 1;
+  static const screenSettings = ScreenItem(
+    code: 'screen_settings',
+    icon: Icon(UniconsLine.setting),
+    screen: ScreenSettings(),
+  );
+
+  static const indexAbout = 2;
+  static const screenAbout = ScreenItem(
+    code: 'screen_about',
+    icon: Icon(UniconsLine.info_circle),
+    screen: ScreenAbout(),
+  );
+
+  static Map<int, ScreenItem> items = {
+    indexActivity: screenActivity,
+    indexSettings: screenSettings,
+    indexAbout: screenAbout,
+  };
+
+  static bool isIndexAllowed(int screenIndex) {
+    return items.keys.contains(screenIndex);
+  }
+
+  static Widget getWidget(int screenIndex) {
+    return items[screenIndex]?.screen ?? screenActivity.screen;
+  }
+}
diff --git a/lib/common/cubit/nav/nav_cubit_pages.dart b/lib/common/cubit/nav/nav_cubit_pages.dart
new file mode 100644
index 0000000..b2dc71b
--- /dev/null
+++ b/lib/common/cubit/nav/nav_cubit_pages.dart
@@ -0,0 +1,33 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/config/activity_page.dart';
+
+class NavCubitPage extends HydratedCubit<int> {
+  NavCubitPage() : super(0);
+
+  void updateIndex(int index) {
+    if (ActivityPage.isIndexAllowed(index)) {
+      emit(index);
+    } else {
+      emit(ActivityPage.indexHome);
+    }
+  }
+
+  void goToPageHome() {
+    updateIndex(ActivityPage.indexHome);
+  }
+
+  void goToPageGame() {
+    updateIndex(ActivityPage.indexGame);
+  }
+
+  @override
+  int fromJson(Map<String, dynamic> json) {
+    return ActivityPage.indexHome;
+  }
+
+  @override
+  Map<String, dynamic>? toJson(int state) {
+    return <String, int>{'index': state};
+  }
+}
diff --git a/lib/common/cubit/nav/nav_cubit_screens.dart b/lib/common/cubit/nav/nav_cubit_screens.dart
new file mode 100644
index 0000000..e0ccaa6
--- /dev/null
+++ b/lib/common/cubit/nav/nav_cubit_screens.dart
@@ -0,0 +1,37 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/config/screen.dart';
+
+class NavCubitScreen extends HydratedCubit<int> {
+  NavCubitScreen() : super(0);
+
+  void updateIndex(int index) {
+    if (Screen.isIndexAllowed(index)) {
+      emit(index);
+    } else {
+      goToScreenActivity();
+    }
+  }
+
+  void goToScreenActivity() {
+    emit(Screen.indexActivity);
+  }
+
+  void goToScreenSettings() {
+    emit(Screen.indexSettings);
+  }
+
+  void goToScreenAbout() {
+    emit(Screen.indexAbout);
+  }
+
+  @override
+  int fromJson(Map<String, dynamic> json) {
+    return Screen.indexActivity;
+  }
+
+  @override
+  Map<String, dynamic>? toJson(int state) {
+    return <String, int>{'index': state};
+  }
+}
diff --git a/lib/common/ui/nav/bottom_nav_bar.dart b/lib/common/ui/nav/bottom_nav_bar.dart
new file mode 100644
index 0000000..613cb7f
--- /dev/null
+++ b/lib/common/ui/nav/bottom_nav_bar.dart
@@ -0,0 +1,46 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/config/activity_page.dart';
+import 'package:random/common/cubit/nav/nav_cubit_pages.dart';
+
+class BottomNavBar extends StatelessWidget {
+  const BottomNavBar({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Card(
+      margin: const EdgeInsets.only(top: 1, right: 4, left: 4),
+      elevation: 4,
+      shadowColor: Theme.of(context).colorScheme.shadow,
+      color: Theme.of(context).colorScheme.surfaceContainerHighest,
+      shape: const RoundedRectangleBorder(
+        borderRadius: BorderRadius.only(
+          topLeft: Radius.circular(16),
+          topRight: Radius.circular(16),
+        ),
+      ),
+      child: BlocBuilder<NavCubitPage, int>(builder: (BuildContext context, int state) {
+        final List<BottomNavigationBarItem> items = [];
+
+        ActivityPage.items.forEach((int pageIndex, ActivityPageItem item) {
+          items.add(BottomNavigationBarItem(
+            icon: item.icon,
+            label: tr(item.code),
+          ));
+        });
+
+        return BottomNavigationBar(
+          currentIndex: state,
+          onTap: (int index) => BlocProvider.of<NavCubitPage>(context).updateIndex(index),
+          type: BottomNavigationBarType.fixed,
+          elevation: 0,
+          backgroundColor: Colors.transparent,
+          selectedItemColor: Theme.of(context).colorScheme.primary,
+          unselectedItemColor: Theme.of(context).textTheme.bodySmall!.color,
+          items: items,
+        );
+      }),
+    );
+  }
+}
diff --git a/lib/common/ui/nav/global_app_bar.dart b/lib/common/ui/nav/global_app_bar.dart
new file mode 100644
index 0000000..6a08a3a
--- /dev/null
+++ b/lib/common/ui/nav/global_app_bar.dart
@@ -0,0 +1,86 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/config/screen.dart';
+import 'package:random/common/cubit/nav/nav_cubit_pages.dart';
+import 'package:random/common/cubit/nav/nav_cubit_screens.dart';
+
+import 'package:random/cubit/activity/activity_cubit.dart';
+import 'package:random/models/activity/activity.dart';
+
+class GlobalAppBar extends StatelessWidget implements PreferredSizeWidget {
+  const GlobalAppBar({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        return BlocBuilder<NavCubitScreen, int>(
+          builder: (BuildContext context, int pageIndex) {
+            final Activity currentActivity = activityState.currentActivity;
+
+            final List<Widget> menuActions = [];
+
+            if (currentActivity.isRunning && !currentActivity.isFinished) {
+              menuActions.add(StyledButton(
+                color: Colors.red,
+                onPressed: () {},
+                onLongPress: () {
+                  BlocProvider.of<ActivityCubit>(context).quitActivity();
+                  BlocProvider.of<NavCubitPage>(context).goToPageHome();
+                },
+                child: const Image(
+                  image: AssetImage('assets/ui/button_back.png'),
+                  fit: BoxFit.fill,
+                ),
+              ));
+            } else {
+              if (pageIndex == Screen.indexActivity) {
+                // go to Settings page
+                menuActions.add(ElevatedButton(
+                  onPressed: () {
+                    BlocProvider.of<NavCubitScreen>(context).goToScreenSettings();
+                  },
+                  style: ElevatedButton.styleFrom(
+                    shape: const CircleBorder(),
+                  ),
+                  child: Screen.screenSettings.icon,
+                ));
+
+                // go to About page
+                menuActions.add(ElevatedButton(
+                  onPressed: () {
+                    BlocProvider.of<NavCubitScreen>(context).goToScreenAbout();
+                  },
+                  style: ElevatedButton.styleFrom(
+                    shape: const CircleBorder(),
+                  ),
+                  child: Screen.screenAbout.icon,
+                ));
+              } else {
+                // back to Home page
+                menuActions.add(ElevatedButton(
+                  onPressed: () {
+                    BlocProvider.of<NavCubitScreen>(context).goToScreenActivity();
+                  },
+                  style: ElevatedButton.styleFrom(
+                    shape: const CircleBorder(),
+                  ),
+                  child: Screen.screenActivity.icon,
+                ));
+              }
+            }
+
+            return AppBar(
+              title: const AppHeader(text: 'app_name'),
+              actions: menuActions,
+            );
+          },
+        );
+      },
+    );
+  }
+
+  @override
+  Size get preferredSize => const Size.fromHeight(50);
+}
diff --git a/lib/ui/screens/api_page.dart b/lib/common/ui/pages/api.dart
similarity index 82%
rename from lib/ui/screens/api_page.dart
rename to lib/common/ui/pages/api.dart
index b9a2b22..4fe13e2 100644
--- a/lib/ui/screens/api_page.dart
+++ b/lib/common/ui/pages/api.dart
@@ -1,13 +1,13 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/cubit/api_cubit.dart';
+import 'package:random/cubit/activity/api_cubit.dart';
 import 'package:random/models/api_status.dart';
+import 'package:random/ui/widgets/custom_title.dart';
 import 'package:random/ui/widgets/api_data.dart';
-import 'package:random/ui/widgets/header_app.dart';
 
-class ApiPage extends StatelessWidget {
-  const ApiPage({super.key});
+class PageApi extends StatelessWidget {
+  const PageApi({super.key});
 
   @override
   Widget build(BuildContext context) {
@@ -18,7 +18,7 @@ class ApiPage extends StatelessWidget {
         physics: const BouncingScrollPhysics(),
         children: <Widget>[
           const SizedBox(height: 8),
-          const AppHeaderCustom(text: 'api_page_title'),
+          const CustomTitle(text: 'api_page_title'),
           const SizedBox(height: 20),
           BlocBuilder<ApiDataCubit, ApiDataState>(
             builder: (BuildContext context, ApiDataState apiDataState) {
diff --git a/lib/ui/screens/camera_page.dart b/lib/common/ui/pages/camera.dart
similarity index 82%
rename from lib/ui/screens/camera_page.dart
rename to lib/common/ui/pages/camera.dart
index ca4df4c..71ba41e 100644
--- a/lib/ui/screens/camera_page.dart
+++ b/lib/common/ui/pages/camera.dart
@@ -3,11 +3,11 @@ import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/ui/widgets/take_picture_widget.dart';
 
-class CameraPage extends StatelessWidget {
-  const CameraPage({super.key});
+class PageCamera extends StatelessWidget {
+  const PageCamera({super.key});
 
   static Icon navBarIcon = const Icon(UniconsLine.camera);
-  static String navBarText = 'bottom_nav_camera';
+  static String navBarText = 'page_camera';
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/common/ui/pages/demo.dart b/lib/common/ui/pages/demo.dart
new file mode 100644
index 0000000..1988e22
--- /dev/null
+++ b/lib/common/ui/pages/demo.dart
@@ -0,0 +1,195 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/cubit/activity/data_cubit.dart';
+import 'package:random/cubit/settings/settings_cubit.dart';
+import 'package:random/ui/widgets/custom_title.dart';
+
+class PageDemo extends StatelessWidget {
+  const PageDemo({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return ListView(
+      padding: const EdgeInsets.symmetric(horizontal: 4),
+      physics: const BouncingScrollPhysics(),
+      children: <Widget>[
+        const SizedBox(height: 8),
+        const CustomTitle(text: 'TOP'),
+        const SizedBox(height: 20),
+        StyledContainer(
+          child: persistedCounterBlock(BlocProvider.of<DataCubit>(context)),
+        ),
+        const SizedBox(height: 8),
+        StyledContainer(
+          borderRadius: 0,
+          borderWidth: 12,
+          // depth: 8,
+          lowerColor: Colors.red,
+          upperColor: Colors.yellow,
+          child: testBlocConsumer(),
+        ),
+        const SizedBox(height: 8),
+        StyledContainer(
+          borderRadius: 10,
+          borderWidth: 30,
+          depth: 20,
+          lowerColor: Colors.blueGrey,
+          upperColor: Colors.blue,
+          child: testBlocBuilder(),
+        ),
+        const SizedBox(height: 8),
+        fakeApiCall(),
+        const SizedBox(height: 8),
+        const CustomTitle(text: 'BOTTOM'),
+        const SizedBox(height: 8),
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            StyledButton.text(
+              caption: 'ABC',
+              color: Colors.yellow,
+              onPressed: () {
+                printlog('A');
+              },
+            ),
+            StyledButton.text(
+              caption: '❤️‍🔥',
+              color: Colors.red,
+              onPressed: () {
+                printlog('fire!');
+              },
+            ),
+            StyledButton.text(
+              caption: '⭐',
+              color: Colors.green,
+              onPressed: () {
+                printlog('star!');
+              },
+            ),
+            StyledButton.text(
+              caption: '🧁',
+              color: Colors.blue,
+              onPressed: () {
+                printlog('Cupcake');
+              },
+            ),
+            StyledButton.icon(
+              icon: Icon(UniconsLine.setting),
+              color: Colors.purple,
+              iconSize: 20,
+              onPressed: () {
+                printlog('icon');
+              },
+            ),
+          ],
+        ),
+        const SizedBox(height: 8),
+        StyledButton.text(
+          caption: 'BUTTON - LARGE',
+          color: Colors.orange,
+          onPressed: () {
+            printlog('large button');
+          },
+        ),
+        const SizedBox(height: 8),
+        Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            TextButton(
+              child: Text('ABC'),
+              onPressed: () {
+                printlog('TextButton');
+              },
+            ),
+            OutlinedButton(
+              child: Text('❤️‍🔥'),
+              onPressed: () {
+                printlog('OutlinedButton');
+              },
+            ),
+            FilledButton(
+              child: Text('⭐'),
+              onPressed: () {
+                printlog('FilledButton');
+              },
+            ),
+            ElevatedButton(
+              child: Text('🧁'),
+              onPressed: () {
+                printlog('ElevatedButton');
+              },
+            ),
+          ],
+        ),
+      ],
+    );
+  }
+
+  Widget persistedCounterBlock(DataCubit dataCubit) {
+    return Row(
+      mainAxisAlignment: MainAxisAlignment.center,
+      crossAxisAlignment: CrossAxisAlignment.center,
+      children: [
+        IconButton(
+          icon: const Icon(UniconsSolid.arrow_circle_down),
+          color: appTheme.primaryColor,
+          onPressed: () => dataCubit.updateCounter(-1),
+        ),
+        testBlocConsumer(),
+        IconButton(
+          icon: const Icon(UniconsSolid.arrow_circle_up),
+          color: appTheme.primaryColor,
+          onPressed: () => dataCubit.updateCounter(1),
+        ),
+      ],
+    );
+  }
+
+  Widget fakeApiCall() {
+    return BlocBuilder<SettingsCubit, SettingsState>(
+      builder: (context, settingsSate) {
+        return Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            Text('apiUrl: ${settingsSate.apiUrl}'),
+            Text('securityToken: ${settingsSate.securityToken}'),
+            Text('interfaceType: ${settingsSate.interfaceType}'),
+          ],
+        );
+      },
+    );
+  }
+
+  Widget testBlocConsumer() {
+    return BlocConsumer<DataCubit, DataState>(
+      listener: (context, dataState) {
+        // do stuff here based on state
+      },
+      builder: (context, dataState) {
+        // return widget here based on state
+        return Text('BlocConsumer / $dataState');
+      },
+    );
+  }
+
+  Widget testBlocListener() {
+    return BlocListener<DataCubit, DataState>(
+      listener: (context, dataState) {
+        // do stuff here based on state
+      },
+    );
+  }
+
+  Widget testBlocBuilder() {
+    return BlocBuilder<DataCubit, DataState>(
+      builder: (context, dataState) {
+        // return widget here based on state
+        return Text('BlocBuilder / $dataState');
+      },
+    );
+  }
+}
diff --git a/lib/ui/screens/game_page.dart b/lib/common/ui/pages/game.dart
similarity index 57%
rename from lib/ui/screens/game_page.dart
rename to lib/common/ui/pages/game.dart
index a8ee1a9..928305b 100644
--- a/lib/ui/screens/game_page.dart
+++ b/lib/common/ui/pages/game.dart
@@ -1,40 +1,39 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/cubit/game_cubit.dart';
-import 'package:random/models/game/game.dart';
-import 'package:random/ui/widgets/game/game_settings.dart';
+import 'package:random/cubit/activity/activity_cubit.dart';
+import 'package:random/models/activity/activity.dart';
 import 'package:random/ui/widgets/game/game_board.dart';
 
-class GamePage extends StatefulWidget {
-  const GamePage({super.key});
+class PageGame extends StatefulWidget {
+  const PageGame({super.key});
 
   @override
-  State<GamePage> createState() => _GamePageState();
+  State<PageGame> createState() => _PageGameState();
 }
 
-class _GamePageState extends State<GamePage> {
+class _PageGameState extends State<PageGame> {
   Widget buildGameActionsBloc(BuildContext context) {
-    return BlocBuilder<GameCubit, GameState>(builder: (context, gameState) {
-      final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
+    return BlocBuilder<ActivityCubit, ActivityState>(builder: (context, activityState) {
+      final ActivityCubit activityCubit = BlocProvider.of<ActivityCubit>(context);
 
       final List<Widget> buttons = [
         IconButton(
           onPressed: () {
-            gameCubit.updateGameState(Game.createNew());
+            activityCubit.updateState(Activity.createNew());
           },
           icon: const Icon(UniconsSolid.star),
           color: Theme.of(context).colorScheme.primary,
         )
       ];
 
-      if (gameState.game?.isRunning == true) {
+      if (activityState.currentActivity.isRunning == true) {
         buttons.add(IconButton(
           onPressed: () {
-            final Game currentGame = gameCubit.state.game!;
-            currentGame.stop();
+            final Activity currentActivity = activityCubit.state.currentActivity;
+            currentActivity.stop();
 
-            gameCubit.updateGameState(currentGame);
+            activityCubit.updateState(currentActivity);
             setState(() {});
           },
           icon: const Icon(UniconsLine.exit),
@@ -55,18 +54,18 @@ class _GamePageState extends State<GamePage> {
     const double boardWidgetWidth = 300;
     const double boardWidgetHeight = 300;
 
-    return BlocBuilder<GameCubit, GameState>(
-      builder: (context, gameState) {
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (context, activityState) {
         return Column(
           mainAxisAlignment: MainAxisAlignment.start,
           crossAxisAlignment: CrossAxisAlignment.center,
           children: [
-            gameState.game?.isRunning == true
+            activityState.currentActivity.isRunning == true
                 ? GameBoardWidget(
-                    game: gameState.game!,
+                    activity: activityState.currentActivity,
                     widgetSize: const Size(boardWidgetWidth, boardWidgetHeight),
                   )
-                : const GameSettingsWidget(),
+                : SizedBox.shrink(),
             buildGameActionsBloc(context),
           ],
         );
diff --git a/lib/ui/screens/graph_page.dart b/lib/common/ui/pages/graph.dart
similarity index 92%
rename from lib/ui/screens/graph_page.dart
rename to lib/common/ui/pages/graph.dart
index 3b6d770..2222146 100644
--- a/lib/ui/screens/graph_page.dart
+++ b/lib/common/ui/pages/graph.dart
@@ -3,14 +3,14 @@ import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/ui/painters/graph_painter.dart';
 
-class GraphPage extends StatefulWidget {
-  const GraphPage({super.key});
+class PageGraph extends StatefulWidget {
+  const PageGraph({super.key});
 
   @override
-  State<GraphPage> createState() => _GraphPageState();
+  State<PageGraph> createState() => _PageGraphState();
 }
 
-class _GraphPageState extends State<GraphPage> {
+class _PageGraphState extends State<PageGraph> {
   double _currentSliderValue = 20;
 
   @override
diff --git a/lib/common/ui/pages/parameters.dart b/lib/common/ui/pages/parameters.dart
new file mode 100644
index 0000000..e37dfda
--- /dev/null
+++ b/lib/common/ui/pages/parameters.dart
@@ -0,0 +1,148 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/ui/parameters/parameter_widget.dart';
+
+import 'package:random/config/default_activity_settings.dart';
+import 'package:random/config/default_global_settings.dart';
+import 'package:random/cubit/activity/activity_cubit.dart';
+import 'package:random/cubit/settings/settings_activity_cubit.dart';
+import 'package:random/cubit/settings/settings_global_cubit.dart';
+import 'package:random/models/activity/activity.dart';
+import 'package:random/ui/widgets/actions/button_delete_saved_game.dart';
+import 'package:random/ui/widgets/actions/button_game_start_new.dart';
+import 'package:random/ui/widgets/actions/button_resume_saved_game.dart';
+
+class PageParameters extends StatelessWidget {
+  const PageParameters({super.key});
+
+  final double separatorHeight = 8.0;
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<ActivityCubit, ActivityState>(
+      builder: (BuildContext context, ActivityState activityState) {
+        final Activity currentActivity = activityState.currentActivity;
+
+        final List<Widget> lines = [];
+
+        // Game settings
+        for (String code in DefaultActivitySettings.availableParameters) {
+          lines.add(Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: buildParametersLine(
+              code: code,
+              isGlobal: false,
+            ),
+          ));
+
+          lines.add(SizedBox(height: separatorHeight));
+        }
+
+        lines.add(Expanded(
+          child: SizedBox(height: separatorHeight),
+        ));
+
+        if (currentActivity.canBeResumed == false) {
+          // Start new game
+          lines.add(
+            const AspectRatio(
+              aspectRatio: 3,
+              child: StartNewGameButton(),
+            ),
+          );
+        } else {
+          // Resume game
+          lines.add(const AspectRatio(
+            aspectRatio: 3,
+            child: ResumeSavedGameButton(),
+          ));
+          // Delete saved game
+          lines.add(SizedBox.square(
+            dimension: MediaQuery.of(context).size.width / 5,
+            child: const DeleteSavedGameButton(),
+          ));
+        }
+
+        lines.add(SizedBox(height: separatorHeight));
+
+        // Global settings
+        for (String code in DefaultGlobalSettings.availableParameters) {
+          lines.add(Row(
+            mainAxisAlignment: MainAxisAlignment.spaceBetween,
+            children: buildParametersLine(
+              code: code,
+              isGlobal: true,
+            ),
+          ));
+
+          lines.add(SizedBox(height: separatorHeight));
+        }
+
+        return Column(
+          children: lines,
+        );
+      },
+    );
+  }
+
+  List<Widget> buildParametersLine({
+    required String code,
+    required bool isGlobal,
+  }) {
+    final List<Widget> parameterButtons = [];
+
+    final List<String> availableValues = isGlobal
+        ? DefaultGlobalSettings.getAvailableValues(code)
+        : DefaultActivitySettings.getAvailableValues(code);
+
+    if (availableValues.length <= 1) {
+      return [];
+    }
+
+    for (String value in availableValues) {
+      final Widget parameterButton = BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
+        builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
+          return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
+            builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
+              final ActivitySettingsCubit activitySettingsCubit =
+                  BlocProvider.of<ActivitySettingsCubit>(context);
+              final GlobalSettingsCubit globalSettingsCubit =
+                  BlocProvider.of<GlobalSettingsCubit>(context);
+
+              final String currentValue = isGlobal
+                  ? globalSettingsCubit.getParameterValue(code)
+                  : activitySettingsCubit.getParameterValue(code);
+
+              final bool isSelected = (value == currentValue);
+
+              final double displayWidth = MediaQuery.of(context).size.width;
+              final double itemWidth = displayWidth / availableValues.length - 4;
+
+              return SizedBox.square(
+                dimension: itemWidth,
+                child: ParameterWidget(
+                  code: code,
+                  value: value,
+                  isSelected: isSelected,
+                  size: itemWidth,
+                  activitySettings: activitySettingsState.settings,
+                  globalSettings: globalSettingsState.settings,
+                  onPressed: () {
+                    isGlobal
+                        ? globalSettingsCubit.setParameterValue(code, value)
+                        : activitySettingsCubit.setParameterValue(code, value);
+                  },
+                ),
+              );
+            },
+          );
+        },
+      );
+
+      parameterButtons.add(parameterButton);
+    }
+
+    return parameterButtons;
+  }
+}
diff --git a/lib/common/ui/parameters/parameter_painter.dart b/lib/common/ui/parameters/parameter_painter.dart
new file mode 100644
index 0000000..92a6c6a
--- /dev/null
+++ b/lib/common/ui/parameters/parameter_painter.dart
@@ -0,0 +1,196 @@
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/config/default_activity_settings.dart';
+import 'package:random/models/settings/settings_activity.dart';
+import 'package:random/models/settings/settings_global.dart';
+
+class ParameterPainter extends CustomPainter {
+  const ParameterPainter({
+    required this.code,
+    required this.value,
+    required this.activitySettings,
+    required this.globalSettings,
+  });
+
+  final String code;
+  final String value;
+  final ActivitySettings activitySettings;
+  final GlobalSettings globalSettings;
+
+  @override
+  void paint(Canvas canvas, Size size) {
+    // force square
+    final double canvasSize = min(size.width, size.height);
+
+    // content
+    switch (code) {
+      case DefaultActivitySettings.parameterCodeBoardSize:
+        paintBoardSizeParameterItem(canvas, canvasSize);
+        break;
+      case DefaultActivitySettings.parameterCodeColorsCount:
+        paintColorsCountParameterItem(canvas, canvasSize);
+        break;
+      default:
+        printlog('$ParameterPainter -> unknown parameter: $code/$value');
+        paintUnknownParameterItem(canvas, canvasSize);
+    }
+  }
+
+  @override
+  bool shouldRepaint(CustomPainter oldDelegate) {
+    return false;
+  }
+
+  // "unknown" parameter -> simple block with text
+  void paintUnknownParameterItem(
+    final Canvas canvas,
+    final double size,
+  ) {
+    final paint = Paint();
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 3;
+
+    final textSpan = TextSpan(
+      text: '$code\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 paintBoardSizeParameterItem(
+    final Canvas canvas,
+    final double size,
+  ) {
+    int gridWidth = 1;
+
+    switch (value) {
+      case DefaultActivitySettings.boardSizeValueSmall:
+        gridWidth = 2;
+        break;
+      case DefaultActivitySettings.boardSizeValueMedium:
+        gridWidth = 3;
+        break;
+      case DefaultActivitySettings.boardSizeValueLarge:
+        gridWidth = 4;
+        break;
+      case DefaultActivitySettings.boardSizeValueExtraLarge:
+        gridWidth = 5;
+        break;
+      default:
+        printlog('Wrong value for boardSize parameter value: $value');
+    }
+
+    final paint = Paint();
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 3 / 100 * size;
+
+    // Mini grid
+    final squareBackgroundColor = Colors.grey.shade200;
+    final squareBorderColor = Colors.grey.shade800;
+
+    final double cellSize = size / 7;
+    final double origin = (size - gridWidth * cellSize) / 2;
+
+    for (int row = 0; row < gridWidth; row++) {
+      for (int col = 0; col < gridWidth; col++) {
+        final Offset topLeft = Offset(origin + col * cellSize, origin + row * cellSize);
+        final Offset bottomRight = topLeft + Offset(cellSize, cellSize);
+
+        paint.color = squareBackgroundColor;
+        paint.style = PaintingStyle.fill;
+        canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+
+        paint.color = squareBorderColor;
+        paint.style = PaintingStyle.stroke;
+        canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+      }
+    }
+  }
+
+  void paintColorsCountParameterItem(
+    final Canvas canvas,
+    final double size,
+  ) {
+    final paint = Paint();
+    paint.strokeJoin = StrokeJoin.round;
+    paint.strokeWidth = 3;
+
+    // Colors preview
+    const List<Offset> positions = [
+      Offset(0, 0),
+      Offset(1, 0),
+      Offset(2, 0),
+      Offset(2, 1),
+      Offset(2, 2),
+      Offset(1, 2),
+      Offset(0, 2),
+      Offset(0, 1),
+    ];
+
+    final double padding = 4 / 100 * size;
+    final double margin = 3 / 100 * size;
+    final double width = ((size - 2 * padding) / 3) - 2 * margin;
+
+    final int maxValue = int.parse(value);
+    for (int colorIndex = 0; colorIndex < maxValue; colorIndex++) {
+      final Offset position = positions[colorIndex];
+
+      final Offset topLeft = Offset(padding + margin + position.dx * (width + 2 * margin),
+          padding + margin + position.dy * (width + 2 * margin));
+
+      final Offset bottomRight = topLeft + Offset(width, width);
+
+      final squareColor = Colors.pink;
+      paint.color = squareColor;
+      paint.style = PaintingStyle.fill;
+      canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+
+      final borderColor = squareColor.darken(20);
+      paint.color = borderColor;
+      paint.style = PaintingStyle.stroke;
+      canvas.drawRect(Rect.fromPoints(topLeft, bottomRight), paint);
+    }
+
+    // centered text value
+    final textSpan = TextSpan(
+      text: value.toString(),
+      style: TextStyle(
+        color: Colors.black,
+        fontSize: size / 4,
+        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,
+      ),
+    );
+  }
+}
diff --git a/lib/common/ui/parameters/parameter_widget.dart b/lib/common/ui/parameters/parameter_widget.dart
new file mode 100644
index 0000000..cec3d7b
--- /dev/null
+++ b/lib/common/ui/parameters/parameter_widget.dart
@@ -0,0 +1,162 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/ui/parameters/parameter_painter.dart';
+
+import 'package:random/config/default_activity_settings.dart';
+import 'package:random/config/default_global_settings.dart';
+import 'package:random/models/settings/settings_activity.dart';
+import 'package:random/models/settings/settings_global.dart';
+
+class ParameterWidget extends StatelessWidget {
+  const ParameterWidget({
+    super.key,
+    required this.code,
+    required this.value,
+    required this.isSelected,
+    required this.size,
+    required this.activitySettings,
+    required this.globalSettings,
+    required this.onPressed,
+  });
+
+  final String code;
+  final String value;
+  final bool isSelected;
+  final double size;
+  final ActivitySettings activitySettings;
+  final GlobalSettings globalSettings;
+  final VoidCallback onPressed;
+
+  static const Color buttonColorActive = Colors.blue;
+  static const Color buttonColorInactive = Colors.white;
+  static const double buttonBorderWidth = 4.0;
+  static const double buttonBorderRadius = 12.0;
+
+  @override
+  Widget build(BuildContext context) {
+    Widget content = const SizedBox.shrink();
+
+    switch (code) {
+      case DefaultActivitySettings.parameterCodeBoardSize:
+        content = getBoardSizeParameterItem();
+        break;
+      case DefaultActivitySettings.parameterCodeColorsCount:
+        content = getColorsCountParameterItem();
+        break;
+      case DefaultGlobalSettings.parameterCodeSkin:
+        content = getSkinParameterItem();
+        break;
+      default:
+        printlog('$ParameterWidget -> unknown parameter: $code/$value');
+        content = getUnknownParameterItem();
+    }
+
+    final Color buttonColor = isSelected ? buttonColorActive : buttonColorInactive;
+
+    return Container(
+      decoration: BoxDecoration(
+        color: buttonColor,
+        borderRadius: BorderRadius.circular(buttonBorderRadius),
+        border: Border.all(
+          color: buttonColor,
+          width: buttonBorderWidth,
+        ),
+      ),
+      child: content,
+    );
+  }
+
+  // "unknown" parameter -> simple block with text
+  Widget getUnknownParameterItem() {
+    return StyledButton.text(
+      caption: '$code / $value',
+      color: Colors.grey,
+      onPressed: null,
+    );
+  }
+
+  Widget getBoardSizeParameterItem() {
+    Color backgroundColor = Colors.grey;
+
+    switch (value) {
+      case DefaultActivitySettings.boardSizeValueSmall:
+        backgroundColor = Colors.green;
+        break;
+      case DefaultActivitySettings.boardSizeValueMedium:
+        backgroundColor = Colors.orange;
+        break;
+      case DefaultActivitySettings.boardSizeValueLarge:
+        backgroundColor = Colors.red;
+        break;
+      case DefaultActivitySettings.boardSizeValueExtraLarge:
+        backgroundColor = Colors.purple;
+        break;
+      default:
+        printlog('Wrong value for size parameter value: $value');
+    }
+
+    return StyledButton(
+      color: backgroundColor,
+      onPressed: onPressed,
+      child: CustomPaint(
+        size: Size(size, size),
+        willChange: false,
+        painter: ParameterPainter(
+          code: code,
+          value: value,
+          activitySettings: activitySettings,
+          globalSettings: globalSettings,
+        ),
+        isComplex: true,
+      ),
+    );
+  }
+
+  Widget getColorsCountParameterItem() {
+    Color backgroundColor = Colors.grey;
+
+    switch (value) {
+      case DefaultActivitySettings.colorsCountVeryLow:
+        backgroundColor = Colors.green;
+        break;
+      case DefaultActivitySettings.colorsCountLow:
+        backgroundColor = Colors.orange;
+        break;
+      case DefaultActivitySettings.colorsCountMedium:
+        backgroundColor = Colors.red;
+        break;
+      case DefaultActivitySettings.colorsCountHigh:
+        backgroundColor = Colors.purple;
+        break;
+      default:
+        printlog('Wrong value for level parameter value: $value');
+    }
+
+    return StyledButton(
+      color: backgroundColor,
+      onPressed: onPressed,
+      child: CustomPaint(
+        size: Size(size, size),
+        willChange: false,
+        painter: ParameterPainter(
+          code: code,
+          value: value,
+          activitySettings: activitySettings,
+          globalSettings: globalSettings,
+        ),
+        isComplex: true,
+      ),
+    );
+  }
+
+  Widget getSkinParameterItem() {
+    Color backgroundColor = Colors.grey;
+
+    return StyledButton(
+      color: backgroundColor,
+      onPressed: onPressed,
+      child: Text('skin: $value'),
+    );
+  }
+}
diff --git a/lib/common/ui/screens/about.dart b/lib/common/ui/screens/about.dart
new file mode 100644
index 0000000..f7a14a9
--- /dev/null
+++ b/lib/common/ui/screens/about.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+class ScreenAbout extends StatelessWidget {
+  const ScreenAbout({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 8),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisSize: MainAxisSize.max,
+        children: <Widget>[
+          const SizedBox(height: 8),
+          const AppTitle(text: 'about_title'),
+          const Text('about_content').tr(),
+          FutureBuilder<PackageInfo>(
+            future: PackageInfo.fromPlatform(),
+            builder: (context, snapshot) {
+              switch (snapshot.connectionState) {
+                case ConnectionState.done:
+                  return const Text('about_version').tr(
+                    namedArgs: {
+                      'version': snapshot.data!.version,
+                    },
+                  );
+                default:
+                  return const SizedBox();
+              }
+            },
+          ),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/common/ui/screens/activity.dart b/lib/common/ui/screens/activity.dart
new file mode 100644
index 0000000..239e1ee
--- /dev/null
+++ b/lib/common/ui/screens/activity.dart
@@ -0,0 +1,18 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/config/activity_page.dart';
+import 'package:random/common/cubit/nav/nav_cubit_pages.dart';
+
+class ScreenActivity extends StatelessWidget {
+  const ScreenActivity({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<NavCubitPage, int>(
+      builder: (BuildContext context, int pageIndex) {
+        return ActivityPage.getWidget(pageIndex);
+      },
+    );
+  }
+}
diff --git a/lib/common/ui/screens/settings.dart b/lib/common/ui/screens/settings.dart
new file mode 100644
index 0000000..8dc117a
--- /dev/null
+++ b/lib/common/ui/screens/settings.dart
@@ -0,0 +1,26 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/ui/settings/settings_form.dart';
+
+class ScreenSettings extends StatelessWidget {
+  const ScreenSettings({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return const Padding(
+      padding: EdgeInsets.symmetric(horizontal: 8),
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.start,
+        crossAxisAlignment: CrossAxisAlignment.start,
+        mainAxisSize: MainAxisSize.max,
+        children: <Widget>[
+          SizedBox(height: 8),
+          AppTitle(text: 'settings_title'),
+          SizedBox(height: 8),
+          SettingsForm(),
+        ],
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/settings_form.dart b/lib/common/ui/settings/settings_form.dart
similarity index 95%
rename from lib/ui/widgets/settings_form.dart
rename to lib/common/ui/settings/settings_form.dart
index 8273e66..7fda5e8 100644
--- a/lib/ui/widgets/settings_form.dart
+++ b/lib/common/ui/settings/settings_form.dart
@@ -1,9 +1,8 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/cubit/settings_cubit.dart';
+import 'package:random/cubit/settings/settings_cubit.dart';
 import 'package:random/models/interface_type.dart';
-import 'package:random/ui/widgets/theme_card.dart';
 
 class SettingsForm extends StatefulWidget {
   const SettingsForm({super.key});
@@ -62,15 +61,15 @@ class _SettingsFormState extends State<SettingsForm> {
               mainAxisAlignment: MainAxisAlignment.end,
               crossAxisAlignment: CrossAxisAlignment.center,
               children: [
-                ThemeCard(
+                ApplicationSettingsThemeModeCard(
                   mode: ThemeMode.system,
                   icon: UniconsLine.cog,
                 ),
-                ThemeCard(
+                ApplicationSettingsThemeModeCard(
                   mode: ThemeMode.light,
                   icon: UniconsLine.sun,
                 ),
-                ThemeCard(
+                ApplicationSettingsThemeModeCard(
                   mode: ThemeMode.dark,
                   icon: UniconsLine.moon,
                 )
diff --git a/lib/config/application_config.dart b/lib/config/application_config.dart
new file mode 100644
index 0000000..8d0a234
--- /dev/null
+++ b/lib/config/application_config.dart
@@ -0,0 +1,3 @@
+class ApplicationConfig {
+  static const String appTitle = 'Random application';
+}
diff --git a/lib/config/default_activity_settings.dart b/lib/config/default_activity_settings.dart
new file mode 100644
index 0000000..5f34d9d
--- /dev/null
+++ b/lib/config/default_activity_settings.dart
@@ -0,0 +1,52 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+class DefaultActivitySettings {
+  // available game parameters codes
+  static const String parameterCodeBoardSize = 'boardSize';
+  static const String parameterCodeColorsCount = 'colorsCount';
+  static const List<String> availableParameters = [
+    parameterCodeBoardSize,
+    parameterCodeColorsCount,
+  ];
+
+  // board size: available values
+  static const String boardSizeValueSmall = '6';
+  static const String boardSizeValueMedium = '10';
+  static const String boardSizeValueLarge = '16';
+  static const String boardSizeValueExtraLarge = '24';
+  static const List<String> allowedBoardSizeValues = [
+    boardSizeValueSmall,
+    boardSizeValueMedium,
+    boardSizeValueLarge,
+    boardSizeValueExtraLarge,
+  ];
+  // board size: default value
+  static const String defaultBoardSizeValue = boardSizeValueLarge;
+
+  // colors count: available values
+  static const String colorsCountVeryLow = '4';
+  static const String colorsCountLow = '5';
+  static const String colorsCountMedium = '6';
+  static const String colorsCountHigh = '7';
+  static const List<String> allowedColorsCountValues = [
+    colorsCountVeryLow,
+    colorsCountLow,
+    colorsCountMedium,
+    colorsCountHigh,
+  ];
+  // colors count: default value
+  static const String defaultColorsCountValue = colorsCountMedium;
+
+  // available values from parameter code
+  static List<String> getAvailableValues(String parameterCode) {
+    switch (parameterCode) {
+      case parameterCodeBoardSize:
+        return DefaultActivitySettings.allowedBoardSizeValues;
+      case parameterCodeColorsCount:
+        return DefaultActivitySettings.allowedColorsCountValues;
+    }
+
+    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..d92229c
--- /dev/null
+++ b/lib/config/default_global_settings.dart
@@ -0,0 +1,28 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.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;
+
+  // available values from parameter code
+  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
deleted file mode 100644
index 69a2ac1..0000000
--- a/lib/config/menu.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:random/ui/screens/about_page.dart';
-import 'package:random/ui/screens/api_page.dart';
-import 'package:random/ui/screens/camera_page.dart';
-import 'package:random/ui/screens/demo_page.dart';
-import 'package:random/ui/screens/game_page.dart';
-import 'package:random/ui/screens/graph_page.dart';
-import 'package:random/ui/screens/settings_page.dart';
-
-class MenuItem {
-  final String code;
-  final Icon icon;
-  final Widget page;
-
-  const MenuItem({
-    required this.code,
-    required this.icon,
-    required this.page,
-  });
-}
-
-class Menu {
-  static List<MenuItem> items = [
-    const MenuItem(
-      code: 'bottom_nav_sample',
-      icon: Icon(UniconsLine.image),
-      page: DemoPage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_api',
-      icon: Icon(UniconsLine.globe),
-      page: ApiPage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_camera',
-      icon: Icon(UniconsLine.camera),
-      page: CameraPage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_chart',
-      icon: Icon(UniconsLine.pen),
-      page: GraphPage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_game',
-      icon: Icon(UniconsLine.star),
-      page: GamePage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_settings',
-      icon: Icon(UniconsLine.setting),
-      page: SettingsPage(),
-    ),
-    const MenuItem(
-      code: 'bottom_nav_about',
-      icon: Icon(UniconsLine.info_circle),
-      page: AboutPage(),
-    ),
-  ];
-
-  static Widget getPageWidget(int pageIndex) {
-    return Padding(
-      padding: const EdgeInsets.symmetric(horizontal: 8),
-      child: Menu.items.elementAt(pageIndex).page,
-    );
-  }
-
-  static List<BottomNavigationBarItem> getMenuItems() {
-    return Menu.items
-        .map((MenuItem item) => BottomNavigationBarItem(
-              icon: item.icon,
-              label: tr(item.code),
-            ))
-        .toList();
-  }
-
-  static int itemsCount = Menu.items.length;
-}
diff --git a/lib/cubit/activity/activity_cubit.dart b/lib/cubit/activity/activity_cubit.dart
new file mode 100644
index 0000000..5fc69c6
--- /dev/null
+++ b/lib/cubit/activity/activity_cubit.dart
@@ -0,0 +1,82 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/models/activity/activity.dart';
+import 'package:random/models/settings/settings_activity.dart';
+import 'package:random/models/settings/settings_global.dart';
+
+part 'activity_state.dart';
+
+class ActivityCubit extends HydratedCubit<ActivityState> {
+  ActivityCubit()
+      : super(ActivityState(
+          currentActivity: Activity.createNull(),
+        ));
+
+  void updateState(Activity activity) {
+    emit(ActivityState(
+      currentActivity: activity,
+    ));
+  }
+
+  void refresh() {
+    final Activity activity = Activity(
+      activitySettings: state.currentActivity.activitySettings,
+      globalSettings: state.currentActivity.globalSettings,
+      isRunning: state.currentActivity.isRunning,
+      board: state.currentActivity.board,
+    );
+    // game.dump();
+
+    updateState(activity);
+  }
+
+  void startNewActivity({
+    required ActivitySettings activitySettings,
+    required GlobalSettings globalSettings,
+  }) {
+    final Activity newActivity = Activity.createNew(
+      // Settings
+      activitySettings: activitySettings,
+      globalSettings: globalSettings,
+    );
+
+    newActivity.dump();
+
+    updateState(newActivity);
+    refresh();
+  }
+
+  void quitActivity() {
+    state.currentActivity.isRunning = false;
+    refresh();
+  }
+
+  void resumeSavedActivity() {
+    state.currentActivity.isRunning = true;
+    refresh();
+  }
+
+  void deleteSavedActivity() {
+    state.currentActivity.isRunning = false;
+    state.currentActivity.isFinished = true;
+    updateState(Activity.createNull());
+    refresh();
+  }
+
+  @override
+  ActivityState? fromJson(Map<String, dynamic> json) {
+    Activity activity = json['currentActivity'] as Activity;
+
+    return ActivityState(
+      currentActivity: activity,
+    );
+  }
+
+  @override
+  Map<String, dynamic>? toJson(ActivityState state) {
+    return <String, dynamic>{
+      'currentActivity': state.currentActivity.toJson(),
+    };
+  }
+}
diff --git a/lib/cubit/activity/activity_state.dart b/lib/cubit/activity/activity_state.dart
new file mode 100644
index 0000000..887b45e
--- /dev/null
+++ b/lib/cubit/activity/activity_state.dart
@@ -0,0 +1,15 @@
+part of 'activity_cubit.dart';
+
+@immutable
+class ActivityState extends Equatable {
+  const ActivityState({
+    required this.currentActivity,
+  });
+
+  final Activity currentActivity;
+
+  @override
+  List<dynamic> get props => <dynamic>[
+        currentActivity,
+      ];
+}
diff --git a/lib/cubit/api_cubit.dart b/lib/cubit/activity/api_cubit.dart
similarity index 100%
rename from lib/cubit/api_cubit.dart
rename to lib/cubit/activity/api_cubit.dart
diff --git a/lib/cubit/api_state.dart b/lib/cubit/activity/api_state.dart
similarity index 100%
rename from lib/cubit/api_state.dart
rename to lib/cubit/activity/api_state.dart
diff --git a/lib/cubit/data_cubit.dart b/lib/cubit/activity/data_cubit.dart
similarity index 100%
rename from lib/cubit/data_cubit.dart
rename to lib/cubit/activity/data_cubit.dart
diff --git a/lib/cubit/data_state.dart b/lib/cubit/activity/data_state.dart
similarity index 100%
rename from lib/cubit/data_state.dart
rename to lib/cubit/activity/data_state.dart
diff --git a/lib/cubit/bottom_nav_cubit.dart b/lib/cubit/bottom_nav_cubit.dart
deleted file mode 100644
index f27411d..0000000
--- a/lib/cubit/bottom_nav_cubit.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:random/config/menu.dart';
-
-class BottomNavCubit extends HydratedCubit<int> {
-  BottomNavCubit() : super(0);
-
-  void updateIndex(int index) {
-    if (isIndexAllowed(index)) {
-      emit(index);
-    } else {
-      goToHomePage();
-    }
-  }
-
-  bool isIndexAllowed(int index) {
-    return (index >= 0) && (index < Menu.itemsCount);
-  }
-
-  void goToHomePage() => emit(0);
-
-  @override
-  int fromJson(Map<String, dynamic> json) {
-    return 0;
-  }
-
-  @override
-  Map<String, dynamic>? toJson(int state) {
-    return <String, int>{'pageIndex': state};
-  }
-}
diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart
deleted file mode 100644
index 1f39160..0000000
--- a/lib/cubit/game_cubit.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-import 'package:flutter/material.dart';
-
-import 'package:random/models/game/game.dart';
-
-part 'game_state.dart';
-
-class GameCubit extends HydratedCubit<GameState> {
-  GameCubit() : super(const GameState());
-
-  void getData(GameState gameState) {
-    emit(gameState);
-  }
-
-  void updateGameState(Game gameData) {
-    emit(GameState(game: gameData));
-  }
-
-  @override
-  GameState? fromJson(Map<String, dynamic> json) {
-    Game game = json['game'] as Game;
-
-    return GameState(
-      game: game,
-    );
-  }
-
-  @override
-  Map<String, dynamic>? toJson(GameState state) {
-    return <String, dynamic>{
-      'game': state.game?.toJson(),
-    };
-  }
-}
diff --git a/lib/cubit/game_state.dart b/lib/cubit/game_state.dart
deleted file mode 100644
index 3e4d0d0..0000000
--- a/lib/cubit/game_state.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-part of 'game_cubit.dart';
-
-@immutable
-class GameState extends Equatable {
-  const GameState({
-    this.game,
-  });
-
-  final Game? game;
-
-  @override
-  List<Object?> get props => <Object?>[
-        game,
-      ];
-}
diff --git a/lib/cubit/settings/settings_activity_cubit.dart b/lib/cubit/settings/settings_activity_cubit.dart
new file mode 100644
index 0000000..d404017
--- /dev/null
+++ b/lib/cubit/settings/settings_activity_cubit.dart
@@ -0,0 +1,72 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/config/default_activity_settings.dart';
+import 'package:random/models/settings/settings_activity.dart';
+
+part 'settings_activity_state.dart';
+
+class ActivitySettingsCubit extends HydratedCubit<ActivitySettingsState> {
+  ActivitySettingsCubit()
+      : super(ActivitySettingsState(settings: ActivitySettings.createDefault()));
+
+  void setValues({
+    String? itemsCount,
+    String? timerValue,
+  }) {
+    emit(
+      ActivitySettingsState(
+        settings: ActivitySettings(
+          boardSize: itemsCount ?? state.settings.boardSize,
+          colorsCount: timerValue ?? state.settings.colorsCount,
+        ),
+      ),
+    );
+  }
+
+  String getParameterValue(String code) {
+    switch (code) {
+      case DefaultActivitySettings.parameterCodeBoardSize:
+        return ActivitySettings.getItemsCountValueFromUnsafe(state.settings.boardSize);
+      case DefaultActivitySettings.parameterCodeColorsCount:
+        return ActivitySettings.getTimerValueFromUnsafe(state.settings.colorsCount);
+    }
+
+    return '';
+  }
+
+  void setParameterValue(String code, String value) {
+    final String itemsCount = code == DefaultActivitySettings.parameterCodeBoardSize
+        ? value
+        : getParameterValue(DefaultActivitySettings.parameterCodeBoardSize);
+    final String timerValue = code == DefaultActivitySettings.parameterCodeColorsCount
+        ? value
+        : getParameterValue(DefaultActivitySettings.parameterCodeColorsCount);
+
+    setValues(
+      itemsCount: itemsCount,
+      timerValue: timerValue,
+    );
+  }
+
+  @override
+  ActivitySettingsState? fromJson(Map<String, dynamic> json) {
+    final String itemsCount = json[DefaultActivitySettings.parameterCodeBoardSize] as String;
+    final String timerValue = json[DefaultActivitySettings.parameterCodeColorsCount] as String;
+
+    return ActivitySettingsState(
+      settings: ActivitySettings(
+        boardSize: itemsCount,
+        colorsCount: timerValue,
+      ),
+    );
+  }
+
+  @override
+  Map<String, dynamic>? toJson(ActivitySettingsState state) {
+    return <String, dynamic>{
+      DefaultActivitySettings.parameterCodeBoardSize: state.settings.boardSize,
+      DefaultActivitySettings.parameterCodeColorsCount: state.settings.colorsCount,
+    };
+  }
+}
diff --git a/lib/cubit/settings/settings_activity_state.dart b/lib/cubit/settings/settings_activity_state.dart
new file mode 100644
index 0000000..2b2de42
--- /dev/null
+++ b/lib/cubit/settings/settings_activity_state.dart
@@ -0,0 +1,15 @@
+part of 'settings_activity_cubit.dart';
+
+@immutable
+class ActivitySettingsState extends Equatable {
+  const ActivitySettingsState({
+    required this.settings,
+  });
+
+  final ActivitySettings settings;
+
+  @override
+  List<dynamic> get props => <dynamic>[
+        settings,
+      ];
+}
diff --git a/lib/cubit/settings_cubit.dart b/lib/cubit/settings/settings_cubit.dart
similarity index 100%
rename from lib/cubit/settings_cubit.dart
rename to lib/cubit/settings/settings_cubit.dart
diff --git a/lib/cubit/settings/settings_global_cubit.dart b/lib/cubit/settings/settings_global_cubit.dart
new file mode 100644
index 0000000..0353c6b
--- /dev/null
+++ b/lib/cubit/settings/settings_global_cubit.dart
@@ -0,0 +1,59 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/config/default_global_settings.dart';
+import 'package:random/models/settings/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/settings_global_state.dart b/lib/cubit/settings/settings_global_state.dart
new file mode 100644
index 0000000..ebcddd7
--- /dev/null
+++ b/lib/cubit/settings/settings_global_state.dart
@@ -0,0 +1,15 @@
+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,
+      ];
+}
diff --git a/lib/cubit/settings_state.dart b/lib/cubit/settings/settings_state.dart
similarity index 100%
rename from lib/cubit/settings_state.dart
rename to lib/cubit/settings/settings_state.dart
diff --git a/lib/main.dart b/lib/main.dart
index 1437a56..a40d00d 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,19 +1,25 @@
 import 'dart:io';
 
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/cubit/api_cubit.dart';
-import 'package:random/cubit/bottom_nav_cubit.dart';
-import 'package:random/cubit/data_cubit.dart';
-import 'package:random/cubit/game_cubit.dart';
-import 'package:random/cubit/settings_cubit.dart';
-import 'package:random/repository/api.dart';
+import 'package:random/common/cubit/nav/nav_cubit_pages.dart';
+import 'package:random/common/cubit/nav/nav_cubit_screens.dart';
+
+import 'package:random/config/application_config.dart';
+import 'package:random/cubit/activity/activity_cubit.dart';
+import 'package:random/cubit/activity/api_cubit.dart';
+import 'package:random/cubit/activity/data_cubit.dart';
+import 'package:random/cubit/settings/settings_activity_cubit.dart';
+import 'package:random/cubit/settings/settings_cubit.dart';
+import 'package:random/cubit/settings/settings_global_cubit.dart';
 import 'package:random/network/api.dart';
+import 'package:random/repository/api.dart';
 import 'package:random/ui/skeleton.dart';
 
 void main() async {
-  /// Initialize packages
+  // Initialize packages
   WidgetsFlutterBinding.ensureInitialized();
   await EasyLocalization.ensureInitialized();
   final Directory tmpDir = await getTemporaryDirectory();
@@ -22,18 +28,17 @@ void main() async {
     storageDirectory: tmpDir,
   );
 
-  runApp(
-    EasyLocalization(
-      path: 'assets/translations',
-      supportedLocales: const <Locale>[
-        Locale('en'),
-        Locale('fr'),
-      ],
-      fallbackLocale: const Locale('en'),
-      useFallbackTranslations: true,
-      child: const MyApp(),
-    ),
-  );
+  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
+      .then((value) => runApp(EasyLocalization(
+            path: 'assets/translations',
+            supportedLocales: const <Locale>[
+              Locale('en'),
+              Locale('fr'),
+            ],
+            fallbackLocale: const Locale('en'),
+            useFallbackTranslations: true,
+            child: const MyApp(),
+          )));
 }
 
 class MyApp extends StatelessWidget {
@@ -43,6 +48,27 @@ class MyApp extends StatelessWidget {
   Widget build(BuildContext context) {
     return MultiBlocProvider(
       providers: [
+        // default providers
+        BlocProvider<NavCubitPage>(
+          create: (context) => NavCubitPage(),
+        ),
+        BlocProvider<NavCubitScreen>(
+          create: (context) => NavCubitScreen(),
+        ),
+        BlocProvider<ApplicationThemeModeCubit>(
+          create: (context) => ApplicationThemeModeCubit(),
+        ),
+        BlocProvider<ActivityCubit>(
+          create: (context) => ActivityCubit(),
+        ),
+        BlocProvider<GlobalSettingsCubit>(
+          create: (context) => GlobalSettingsCubit(),
+        ),
+        BlocProvider<ActivitySettingsCubit>(
+          create: (context) => ActivitySettingsCubit(),
+        ),
+
+        // custom providers
         BlocProvider<ApiDataCubit>(
           create: (context) => ApiDataCubit(
             apiRepository: ApiRepository(
@@ -50,27 +76,35 @@ class MyApp extends StatelessWidget {
             ),
           )..fetchApiData(),
         ),
-        BlocProvider<BottomNavCubit>(create: (context) => BottomNavCubit()),
-        BlocProvider<DataCubit>(create: (context) => DataCubit()),
-        BlocProvider<GameCubit>(create: (context) => GameCubit()),
-        BlocProvider<SettingsCubit>(create: (context) => SettingsCubit()),
-        BlocProvider<ApplicationThemeModeCubit>(
-            create: (context) => ApplicationThemeModeCubit()),
+        BlocProvider<DataCubit>(
+          create: (context) => DataCubit(),
+        ),
+        BlocProvider<ActivityCubit>(
+          create: (context) => ActivityCubit(),
+        ),
+        BlocProvider<SettingsCubit>(
+          create: (context) => SettingsCubit(),
+        ),
       ],
       child: BlocBuilder<ApplicationThemeModeCubit, ApplicationThemeModeState>(
-          builder: (BuildContext context, ApplicationThemeModeState state) {
-        return MaterialApp(
-          title: 'Random application',
-          theme: lightTheme,
-          darkTheme: darkTheme,
-          themeMode: state.themeMode,
-          home: const SkeletonScreen(),
-          localizationsDelegates: context.localizationDelegates,
-          supportedLocales: context.supportedLocales,
-          locale: context.locale,
-          debugShowCheckedModeBanner: false,
-        );
-      }),
+        builder: (BuildContext context, ApplicationThemeModeState state) {
+          return MaterialApp(
+            title: ApplicationConfig.appTitle,
+            home: const SkeletonScreen(),
+
+            // Theme stuff
+            theme: lightTheme,
+            darkTheme: darkTheme,
+            themeMode: state.themeMode,
+
+            // Localization stuff
+            localizationsDelegates: context.localizationDelegates,
+            supportedLocales: context.supportedLocales,
+            locale: context.locale,
+            debugShowCheckedModeBanner: false,
+          );
+        },
+      ),
     );
   }
 }
diff --git a/lib/models/game/game.dart b/lib/models/activity/activity.dart
similarity index 50%
rename from lib/models/game/game.dart
rename to lib/models/activity/activity.dart
index 966b251..c3d4875 100644
--- a/lib/models/game/game.dart
+++ b/lib/models/activity/activity.dart
@@ -2,38 +2,48 @@ import 'dart:math';
 
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/models/game/game_board.dart';
-import 'package:random/models/game/game_cell.dart';
-import 'package:random/models/game/game_settings.dart';
+import 'package:random/models/activity/game_board.dart';
+import 'package:random/models/activity/game_cell.dart';
+import 'package:random/models/settings/settings_activity.dart';
+import 'package:random/models/settings/settings_global.dart';
 
-class Game {
+class Activity {
   GameBoard board;
-  GameSettings settings;
+  ActivitySettings activitySettings;
+  GlobalSettings globalSettings;
   bool isRunning = false;
   bool isFinished = false;
   int availableBlocksCount = 0;
   int movesCount = 0;
   int score = 0;
 
-  Game({
+  Activity({
     required this.board,
-    required this.settings,
+    required this.activitySettings,
+    required this.globalSettings,
     this.isRunning = false,
   });
 
-  factory Game.createNull() {
-    return Game(
+  factory Activity.createNull() {
+    return Activity(
       board: GameBoard.createNull(),
-      settings: GameSettings.createDefault(),
+      activitySettings: ActivitySettings.createDefault(),
+      globalSettings: GlobalSettings.createDefault(),
     );
   }
 
-  factory Game.createNew({GameSettings? gameSettings}) {
-    GameSettings settings = gameSettings ?? GameSettings.createDefault();
-
-    return Game(
-      board: GameBoard.createRandom(settings),
-      settings: settings,
+  factory Activity.createNew({
+    ActivitySettings? activitySettings,
+    GlobalSettings? globalSettings,
+  }) {
+    ActivitySettings newActivitySettings =
+        activitySettings ?? ActivitySettings.createDefault();
+    GlobalSettings newGlobalSettings = globalSettings ?? GlobalSettings.createDefault();
+
+    return Activity(
+      board: GameBoard.createRandom(newActivitySettings),
+      activitySettings: newActivitySettings,
+      globalSettings: newGlobalSettings,
       isRunning: true,
     );
   }
@@ -43,6 +53,8 @@ class Game {
     isFinished = true;
   }
 
+  bool get canBeResumed => !isFinished && isRunning;
+
   GameCell getCell(int x, int y) {
     return board.cells[y][x];
   }
@@ -55,8 +67,8 @@ class Game {
     board.cells[y][x].value = value;
   }
 
-  void setRandomCellValue(int x, int y, GameSettings settings) {
-    final int maxValue = settings.colorsCount;
+  void setRandomCellValue(int x, int y, ActivitySettings settings) {
+    final int maxValue = settings.colorsCountValue;
     final rand = Random();
     int value = 1 + rand.nextInt(maxValue);
 
@@ -79,7 +91,7 @@ class Game {
   Map<String, dynamic>? toJson() {
     return <String, dynamic>{
       'board': board.toJson(),
-      'settings': settings.toJson(),
+      'settings': activitySettings.toJson(),
       'isRunning': isRunning,
       'isFinished': isFinished,
       'availableBlocksCount': availableBlocksCount,
@@ -90,7 +102,7 @@ class Game {
 
   void dump() {
     GameBoard.printGrid(board.cells);
-    printlog(settings.toString());
+    printlog(activitySettings.toString());
     printlog(toString());
   }
 }
diff --git a/lib/models/game/game_board.dart b/lib/models/activity/game_board.dart
similarity index 76%
rename from lib/models/game/game_board.dart
rename to lib/models/activity/game_board.dart
index 8f0135e..d5854f8 100644
--- a/lib/models/game/game_board.dart
+++ b/lib/models/activity/game_board.dart
@@ -2,8 +2,8 @@ import 'dart:math';
 
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/models/game/game_cell.dart';
-import 'package:random/models/game/game_settings.dart';
+import 'package:random/models/activity/game_cell.dart';
+import 'package:random/models/settings/settings_activity.dart';
 
 class GameBoard {
   final List<List<GameCell>> cells;
@@ -16,10 +16,10 @@ class GameBoard {
     return GameBoard(cells: []);
   }
 
-  factory GameBoard.createRandom(GameSettings gameSettings) {
-    final int boardSizeHorizontal = gameSettings.boardSize;
-    final int boardSizeVertical = gameSettings.boardSize;
-    final int maxValue = gameSettings.colorsCount;
+  factory GameBoard.createRandom(ActivitySettings activitySettings) {
+    final int boardSizeHorizontal = activitySettings.boardSizeValue;
+    final int boardSizeVertical = activitySettings.boardSizeValue;
+    final int maxValue = activitySettings.colorsCountValue;
 
     final rand = Random();
 
diff --git a/lib/models/game/game_cell.dart b/lib/models/activity/game_cell.dart
similarity index 100%
rename from lib/models/game/game_cell.dart
rename to lib/models/activity/game_cell.dart
diff --git a/lib/models/game/game_settings.dart b/lib/models/game/game_settings.dart
deleted file mode 100644
index 2b108da..0000000
--- a/lib/models/game/game_settings.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-class DefaultGameSettings {
-  static const int defaultBoardSizeValue = 6;
-  static const List<int> allowedBoardSizeValues = [
-    5,
-    6,
-    10,
-    15,
-  ];
-
-  static const int defaultColorsCountValue = 7;
-  static const List<int> allowedColorsCountValues = [
-    4,
-    5,
-    6,
-    7,
-  ];
-}
-
-class GameSettings {
-  final int boardSize;
-  final int colorsCount;
-
-  GameSettings({
-    required this.boardSize,
-    required this.colorsCount,
-  });
-
-  factory GameSettings.createDefault() {
-    return GameSettings(
-      boardSize: DefaultGameSettings.defaultBoardSizeValue,
-      colorsCount: DefaultGameSettings.defaultColorsCountValue,
-    );
-  }
-
-  @override
-  String toString() {
-    return 'GameSettings(${toJson()})';
-  }
-
-  Map<String, dynamic>? toJson() {
-    return <String, dynamic>{
-      'boardSize': boardSize,
-      'colorsCount': colorsCount,
-    };
-  }
-}
diff --git a/lib/models/settings/settings_activity.dart b/lib/models/settings/settings_activity.dart
new file mode 100644
index 0000000..4346eba
--- /dev/null
+++ b/lib/models/settings/settings_activity.dart
@@ -0,0 +1,59 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/config/default_activity_settings.dart';
+
+class ActivitySettings {
+  final String boardSize;
+  final String colorsCount;
+
+  ActivitySettings({
+    required this.boardSize,
+    required this.colorsCount,
+  });
+
+  // Getters to convert String to int
+  int get boardSizeValue => int.parse(boardSize);
+  int get colorsCountValue => int.parse(colorsCount);
+
+  static String getItemsCountValueFromUnsafe(String itemsCount) {
+    if (DefaultActivitySettings.allowedBoardSizeValues.contains(itemsCount)) {
+      return itemsCount;
+    }
+
+    return DefaultActivitySettings.defaultBoardSizeValue;
+  }
+
+  static String getTimerValueFromUnsafe(String timerValue) {
+    if (DefaultActivitySettings.allowedColorsCountValues.contains(timerValue)) {
+      return timerValue;
+    }
+
+    return DefaultActivitySettings.defaultColorsCountValue;
+  }
+
+  factory ActivitySettings.createDefault() {
+    return ActivitySettings(
+      boardSize: DefaultActivitySettings.defaultBoardSizeValue,
+      colorsCount: DefaultActivitySettings.defaultColorsCountValue,
+    );
+  }
+
+  void dump() {
+    printlog('$ActivitySettings:');
+    printlog('  ${DefaultActivitySettings.parameterCodeBoardSize}: $boardSize');
+    printlog('  ${DefaultActivitySettings.parameterCodeColorsCount}: $colorsCount');
+    printlog('');
+  }
+
+  @override
+  String toString() {
+    return '$ActivitySettings(${toJson()})';
+  }
+
+  Map<String, dynamic>? toJson() {
+    return <String, dynamic>{
+      DefaultActivitySettings.parameterCodeBoardSize: boardSize,
+      DefaultActivitySettings.parameterCodeColorsCount: colorsCount,
+    };
+  }
+}
diff --git a/lib/models/settings/settings_global.dart b/lib/models/settings/settings_global.dart
new file mode 100644
index 0000000..c8b1fd6
--- /dev/null
+++ b/lib/models/settings/settings_global.dart
@@ -0,0 +1,42 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/config/default_global_settings.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/ui/screens/about_page.dart b/lib/ui/screens/about_page.dart
deleted file mode 100644
index 7903553..0000000
--- a/lib/ui/screens/about_page.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-import 'package:flutter/material.dart';
-
-import 'package:random/ui/widgets/header_app.dart';
-
-class AboutPage extends StatelessWidget {
-  const AboutPage({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return Column(
-      mainAxisAlignment: MainAxisAlignment.start,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      mainAxisSize: MainAxisSize.max,
-      children: <Widget>[
-        const SizedBox(height: 8),
-        const AppHeaderCustom(text: 'about_title'),
-        const Text('about_content').tr(),
-        FutureBuilder<PackageInfo>(
-          future: PackageInfo.fromPlatform(),
-          builder: (context, snapshot) {
-            switch (snapshot.connectionState) {
-              case ConnectionState.done:
-                return const Text('about_version').tr(
-                  namedArgs: {
-                    'version': snapshot.data!.version,
-                  },
-                );
-              default:
-                return const SizedBox();
-            }
-          },
-        ),
-      ],
-    );
-  }
-}
diff --git a/lib/ui/screens/demo_page.dart b/lib/ui/screens/demo_page.dart
deleted file mode 100644
index a7b4e83..0000000
--- a/lib/ui/screens/demo_page.dart
+++ /dev/null
@@ -1,198 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-import 'package:random/cubit/data_cubit.dart';
-import 'package:random/cubit/settings_cubit.dart';
-import 'package:random/ui/widgets/header_app.dart';
-
-class DemoPage extends StatelessWidget {
-  const DemoPage({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return Material(
-      color: Theme.of(context).colorScheme.surface,
-      child: ListView(
-        padding: const EdgeInsets.symmetric(horizontal: 4),
-        physics: const BouncingScrollPhysics(),
-        children: <Widget>[
-          const SizedBox(height: 8),
-          const AppHeaderCustom(text: 'TOP'),
-          const SizedBox(height: 20),
-          StyledContainer(
-            child: persistedCounterBlock(BlocProvider.of<DataCubit>(context)),
-          ),
-          const SizedBox(height: 8),
-          StyledContainer(
-            borderRadius: 0,
-            borderWidth: 12,
-            // depth: 8,
-            lowerColor: Colors.red,
-            upperColor: Colors.yellow,
-            child: testBlocConsumer(),
-          ),
-          const SizedBox(height: 8),
-          StyledContainer(
-            borderRadius: 10,
-            borderWidth: 30,
-            depth: 20,
-            lowerColor: Colors.blueGrey,
-            upperColor: Colors.blue,
-            child: testBlocBuilder(),
-          ),
-          const SizedBox(height: 8),
-          fakeApiCall(),
-          const SizedBox(height: 8),
-          const AppHeaderCustom(text: 'BOTTOM'),
-          const SizedBox(height: 8),
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              StyledButton.text(
-                caption: 'ABC',
-                color: Colors.yellow,
-                onPressed: () {
-                  printlog('A');
-                },
-              ),
-              StyledButton.text(
-                caption: '❤️‍🔥',
-                color: Colors.red,
-                onPressed: () {
-                  printlog('fire!');
-                },
-              ),
-              StyledButton.text(
-                caption: '⭐',
-                color: Colors.green,
-                onPressed: () {
-                  printlog('star!');
-                },
-              ),
-              StyledButton.text(
-                caption: '🧁',
-                color: Colors.blue,
-                onPressed: () {
-                  printlog('Cupcake');
-                },
-              ),
-              StyledButton.icon(
-                icon: Icon(UniconsLine.setting),
-                color: Colors.purple,
-                iconSize: 20,
-                onPressed: () {
-                  printlog('icon');
-                },
-              ),
-            ],
-          ),
-          const SizedBox(height: 8),
-          StyledButton.text(
-            caption: 'BUTTON - LARGE',
-            color: Colors.orange,
-            onPressed: () {
-              printlog('large button');
-            },
-          ),
-          const SizedBox(height: 8),
-          Row(
-            mainAxisAlignment: MainAxisAlignment.spaceBetween,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            children: [
-              TextButton(
-                child: Text('ABC'),
-                onPressed: () {
-                  printlog('TextButton');
-                },
-              ),
-              OutlinedButton(
-                child: Text('❤️‍🔥'),
-                onPressed: () {
-                  printlog('OutlinedButton');
-                },
-              ),
-              FilledButton(
-                child: Text('⭐'),
-                onPressed: () {
-                  printlog('FilledButton');
-                },
-              ),
-              ElevatedButton(
-                child: Text('🧁'),
-                onPressed: () {
-                  printlog('ElevatedButton');
-                },
-              ),
-            ],
-          ),
-        ],
-      ),
-    );
-  }
-
-  Widget persistedCounterBlock(DataCubit dataCubit) {
-    return Row(
-      mainAxisAlignment: MainAxisAlignment.center,
-      crossAxisAlignment: CrossAxisAlignment.center,
-      children: [
-        IconButton(
-          icon: const Icon(UniconsSolid.arrow_circle_down),
-          color: appTheme.primaryColor,
-          onPressed: () => dataCubit.updateCounter(-1),
-        ),
-        testBlocConsumer(),
-        IconButton(
-          icon: const Icon(UniconsSolid.arrow_circle_up),
-          color: appTheme.primaryColor,
-          onPressed: () => dataCubit.updateCounter(1),
-        ),
-      ],
-    );
-  }
-
-  Widget fakeApiCall() {
-    return BlocBuilder<SettingsCubit, SettingsState>(
-      builder: (context, settingsSate) {
-        return Column(
-          mainAxisAlignment: MainAxisAlignment.center,
-          crossAxisAlignment: CrossAxisAlignment.center,
-          children: [
-            Text('apiUrl: ${settingsSate.apiUrl}'),
-            Text('securityToken: ${settingsSate.securityToken}'),
-            Text('interfaceType: ${settingsSate.interfaceType}'),
-          ],
-        );
-      },
-    );
-  }
-
-  Widget testBlocConsumer() {
-    return BlocConsumer<DataCubit, DataState>(
-      listener: (context, dataState) {
-        // do stuff here based on state
-      },
-      builder: (context, dataState) {
-        // return widget here based on state
-        return Text('BlocConsumer / $dataState');
-      },
-    );
-  }
-
-  Widget testBlocListener() {
-    return BlocListener<DataCubit, DataState>(
-      listener: (context, dataState) {
-        // do stuff here based on state
-      },
-    );
-  }
-
-  Widget testBlocBuilder() {
-    return BlocBuilder<DataCubit, DataState>(
-      builder: (context, dataState) {
-        // return widget here based on state
-        return Text('BlocBuilder / $dataState');
-      },
-    );
-  }
-}
diff --git a/lib/ui/screens/settings_page.dart b/lib/ui/screens/settings_page.dart
deleted file mode 100644
index 6995b42..0000000
--- a/lib/ui/screens/settings_page.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:random/ui/widgets/header_app.dart';
-import 'package:random/ui/widgets/settings_form.dart';
-
-class SettingsPage extends StatelessWidget {
-  const SettingsPage({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return const Column(
-      mainAxisAlignment: MainAxisAlignment.start,
-      crossAxisAlignment: CrossAxisAlignment.start,
-      mainAxisSize: MainAxisSize.max,
-      children: <Widget>[
-        SizedBox(height: 8),
-        AppHeaderCustom(text: 'settings_title'),
-        SizedBox(height: 8),
-        SettingsForm(),
-      ],
-    );
-  }
-}
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index 3d71d26..7649abe 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -1,40 +1,37 @@
-import 'package:curved_navigation_bar/curved_navigation_bar.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/config/menu.dart';
-import 'package:random/cubit/bottom_nav_cubit.dart';
-import 'package:random/ui/widgets/app_bar.dart';
+import 'package:random/common/config/activity_page.dart';
+import 'package:random/common/config/screen.dart';
+import 'package:random/common/cubit/nav/nav_cubit_screens.dart';
+import 'package:random/common/ui/nav/global_app_bar.dart';
+import 'package:random/common/ui/nav/bottom_nav_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) {
-    return Scaffold(
-      extendBodyBehindAppBar: false,
-      appBar: const StandardAppBar(),
-      body: BlocBuilder<BottomNavCubit, int>(
-        builder: (context, pageIndex) {
-          return Menu.getPageWidget(pageIndex);
-        },
-      ),
-      backgroundColor: Theme.of(context).colorScheme.surface,
-      bottomNavigationBar: CurvedNavigationBar(
-        color: Theme.of(context).colorScheme.onSurface,
-        backgroundColor: Theme.of(context).colorScheme.surface,
-        animationDuration: const Duration(milliseconds: 200),
-        height: 50,
-        items: Menu.items.map((MenuItem item) => item.icon).toList(),
-        onTap: (newPageIndex) {
-          BlocProvider.of<BottomNavCubit>(context).updateIndex(newPageIndex);
-        },
-      ),
+    return BlocBuilder<NavCubitScreen, int>(
+      builder: (BuildContext context, int screenIndex) {
+        return Scaffold(
+          appBar: const GlobalAppBar(),
+          extendBodyBehindAppBar: false,
+          body: Material(
+            color: Theme.of(context).colorScheme.surface,
+            child: Padding(
+              padding: const EdgeInsets.only(
+                top: 8,
+                left: 2,
+                right: 2,
+              ),
+              child: Screen.getWidget(screenIndex),
+            ),
+          ),
+          backgroundColor: Theme.of(context).colorScheme.surface,
+          bottomNavigationBar: ActivityPage.displayBottomNavBar ? const BottomNavBar() : null,
+        );
+      },
     );
   }
 }
diff --git a/lib/ui/widgets/actions/button_delete_saved_game.dart b/lib/ui/widgets/actions/button_delete_saved_game.dart
new file mode 100644
index 0000000..e6fb9fa
--- /dev/null
+++ b/lib/ui/widgets/actions/button_delete_saved_game.dart
@@ -0,0 +1,22 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/cubit/activity/activity_cubit.dart';
+
+class DeleteSavedGameButton extends StatelessWidget {
+  const DeleteSavedGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return StyledButton(
+      color: Colors.grey,
+      onPressed: () {
+        BlocProvider.of<ActivityCubit>(context).deleteSavedActivity();
+      },
+      child: const Image(
+        image: AssetImage('assets/ui/button_delete_saved_game.png'),
+        fit: BoxFit.fill,
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/actions/button_game_quit.dart b/lib/ui/widgets/actions/button_game_quit.dart
new file mode 100644
index 0000000..14ca1c9
--- /dev/null
+++ b/lib/ui/widgets/actions/button_game_quit.dart
@@ -0,0 +1,25 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/cubit/nav/nav_cubit_pages.dart';
+
+import 'package:random/cubit/activity/activity_cubit.dart';
+
+class QuitGameButton extends StatelessWidget {
+  const QuitGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return StyledButton(
+      color: Colors.red,
+      onPressed: () {
+        BlocProvider.of<ActivityCubit>(context).quitActivity();
+        BlocProvider.of<NavCubitPage>(context).goToPageHome();
+      },
+      child: const Image(
+        image: AssetImage('assets/ui/button_back.png'),
+        fit: BoxFit.fill,
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/actions/button_game_start_new.dart b/lib/ui/widgets/actions/button_game_start_new.dart
new file mode 100644
index 0000000..bb079be
--- /dev/null
+++ b/lib/ui/widgets/actions/button_game_start_new.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/cubit/nav/nav_cubit_pages.dart';
+
+import 'package:random/cubit/activity/activity_cubit.dart';
+import 'package:random/cubit/settings/settings_activity_cubit.dart';
+import 'package:random/cubit/settings/settings_global_cubit.dart';
+
+class StartNewGameButton extends StatelessWidget {
+  const StartNewGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
+      builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
+        return BlocBuilder<GlobalSettingsCubit, GlobalSettingsState>(
+          builder: (BuildContext context, GlobalSettingsState globalSettingsState) {
+            return StyledButton(
+              color: Colors.blue,
+              onPressed: () {
+                BlocProvider.of<ActivityCubit>(context).startNewActivity(
+                  activitySettings: activitySettingsState.settings,
+                  globalSettings: globalSettingsState.settings,
+                );
+                BlocProvider.of<NavCubitPage>(context).goToPageGame();
+              },
+              child: const Image(
+                image: AssetImage('assets/ui/button_start.png'),
+                fit: BoxFit.fill,
+              ),
+            );
+          },
+        );
+      },
+    );
+  }
+}
diff --git a/lib/ui/widgets/actions/button_resume_saved_game.dart b/lib/ui/widgets/actions/button_resume_saved_game.dart
new file mode 100644
index 0000000..41ec5d0
--- /dev/null
+++ b/lib/ui/widgets/actions/button_resume_saved_game.dart
@@ -0,0 +1,25 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
+import 'package:random/common/cubit/nav/nav_cubit_pages.dart';
+
+import 'package:random/cubit/activity/activity_cubit.dart';
+
+class ResumeSavedGameButton extends StatelessWidget {
+  const ResumeSavedGameButton({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return StyledButton(
+      color: Colors.blue,
+      onPressed: () {
+        BlocProvider.of<ActivityCubit>(context).resumeSavedActivity();
+        BlocProvider.of<NavCubitPage>(context).goToPageGame();
+      },
+      child: const Image(
+        image: AssetImage('assets/ui/button_resume_game.png'),
+        fit: BoxFit.fill,
+      ),
+    );
+  }
+}
diff --git a/lib/ui/widgets/app_bar.dart b/lib/ui/widgets/app_bar.dart
deleted file mode 100644
index 7343f6f..0000000
--- a/lib/ui/widgets/app_bar.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-import 'package:flutter/material.dart';
-
-import 'package:random/ui/widgets/header_app.dart';
-
-class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
-  const StandardAppBar({super.key});
-
-  @override
-  Widget build(BuildContext context) {
-    return AppBar(
-      title: const AppHeaderCustom(text: 'app_name'),
-      actions: const [
-        //
-      ],
-    );
-  }
-
-  @override
-  Size get preferredSize => const Size.fromHeight(50);
-}
diff --git a/lib/ui/widgets/header_app.dart b/lib/ui/widgets/custom_title.dart
similarity index 85%
rename from lib/ui/widgets/header_app.dart
rename to lib/ui/widgets/custom_title.dart
index 8670546..99bf427 100644
--- a/lib/ui/widgets/header_app.dart
+++ b/lib/ui/widgets/custom_title.dart
@@ -1,13 +1,13 @@
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter/material.dart';
 
-import 'package:random/cubit/data_cubit.dart';
-import 'package:random/cubit/api_cubit.dart';
-import 'package:random/cubit/settings_cubit.dart';
+import 'package:random/cubit/activity/data_cubit.dart';
+import 'package:random/cubit/activity/api_cubit.dart';
+import 'package:random/cubit/settings/settings_cubit.dart';
 import 'package:random/models/interface_type.dart';
 
-class AppHeaderCustom extends StatelessWidget {
-  const AppHeaderCustom({super.key, required this.text});
+class CustomTitle extends StatelessWidget {
+  const CustomTitle({super.key, required this.text});
 
   final String text;
 
diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart
index 21bd65e..ad9d873 100644
--- a/lib/ui/widgets/game/game_board.dart
+++ b/lib/ui/widgets/game/game_board.dart
@@ -1,20 +1,20 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/cubit/game_cubit.dart';
-import 'package:random/models/game/game.dart';
-import 'package:random/models/game/game_settings.dart';
+import 'package:random/cubit/activity/activity_cubit.dart';
+import 'package:random/models/activity/activity.dart';
+import 'package:random/models/settings/settings_activity.dart';
 import 'package:random/ui/painters/cell_painter.dart';
 import 'package:random/ui/widgets/game/game_score.dart';
 
 class GameBoardWidget extends StatefulWidget {
   const GameBoardWidget({
     super.key,
-    required this.game,
+    required this.activity,
     required this.widgetSize,
   });
 
-  final Game game;
+  final Activity activity;
   final Size widgetSize;
 
   @override
@@ -24,8 +24,8 @@ class GameBoardWidget extends StatefulWidget {
 class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMixin {
   List<List<Animation<double>?>> animations = [];
 
-  void resetAnimations(GameSettings gameSettings) {
-    final boardSize = gameSettings.boardSize;
+  void resetAnimations(ActivitySettings activitySettings) {
+    final int boardSize = activitySettings.boardSizeValue;
 
     animations = List.generate(
       boardSize,
@@ -37,8 +37,8 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi
   }
 
   void removeCell(BuildContext context, int x, int y) {
-    final GameCubit gameCubit = BlocProvider.of<GameCubit>(context);
-    final Game updatedGame = gameCubit.state.game ?? Game.createNew();
+    final ActivityCubit activityCubit = BlocProvider.of<ActivityCubit>(context);
+    final Activity updatedGame = activityCubit.state.currentActivity;
 
     // "remove" cell, update counters
     updatedGame.increaseScore(updatedGame.getCellValue(x, y));
@@ -73,9 +73,9 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi
           for (var i = 0; i < y; i++) {
             updatedGame.updateCellValue(x, (y - i), updatedGame.getCellValue(x, (y - i) - 1));
           }
-          updatedGame.setRandomCellValue(x, 0, updatedGame.settings);
+          updatedGame.setRandomCellValue(x, 0, updatedGame.activitySettings);
 
-          resetAnimations(updatedGame.settings);
+          resetAnimations(updatedGame.activitySettings);
           setState(() {});
 
           controller.dispose();
@@ -90,24 +90,24 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi
   }
 
   Widget buildBoard() {
-    final widgetWidth = widget.widgetSize.width;
-    final widgetHeight = widget.widgetSize.height;
+    final double widgetWidth = widget.widgetSize.width;
+    final double widgetHeight = widget.widgetSize.height;
 
-    final rowsCount = widget.game.settings.boardSize;
-    final columnsCount = widget.game.settings.boardSize;
+    final int rowsCount = widget.activity.activitySettings.boardSizeValue;
+    final int columnsCount = widget.activity.activitySettings.boardSizeValue;
 
-    final cellWidth = widgetWidth / columnsCount;
-    final cellHeight = widgetHeight / rowsCount;
+    final double cellWidth = widgetWidth / columnsCount;
+    final double cellHeight = widgetHeight / rowsCount;
 
     if (animations.isEmpty) {
-      resetAnimations(widget.game.settings);
+      resetAnimations(widget.activity.activitySettings);
     }
 
     final List<Widget> cells = [];
 
     for (var y = 0; y < rowsCount; y++) {
       for (var x = 0; x < columnsCount; x++) {
-        final int? value = widget.game.getCellValue(x, y);
+        final int? value = widget.activity.getCellValue(x, y);
 
         if (value != null) {
           final Animation<double>? translation = animations[y][x];
@@ -144,11 +144,11 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi
   }
 
   Widget interactiveBoard(BuildContext context) {
-    final widgetWidth = widget.widgetSize.width;
-    final widgetHeight = widget.widgetSize.height;
+    final double widgetWidth = widget.widgetSize.width;
+    final double widgetHeight = widget.widgetSize.height;
 
-    final rowsCount = widget.game.settings.boardSize;
-    final columnsCount = widget.game.settings.boardSize;
+    final int rowsCount = widget.activity.activitySettings.boardSizeValue;
+    final int columnsCount = widget.activity.activitySettings.boardSizeValue;
 
     return GestureDetector(
       child: buildBoard(),
@@ -183,7 +183,7 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi
     return Column(
       children: [
         interactiveBoard(context),
-        GameScoreWidget(game: widget.game),
+        GameScoreWidget(activity: widget.activity),
       ],
     );
   }
diff --git a/lib/ui/widgets/game/game_score.dart b/lib/ui/widgets/game/game_score.dart
index cea8f9a..13598e0 100644
--- a/lib/ui/widgets/game/game_score.dart
+++ b/lib/ui/widgets/game/game_score.dart
@@ -1,14 +1,14 @@
 import 'package:flutter/material.dart';
 
-import 'package:random/models/game/game.dart';
+import 'package:random/models/activity/activity.dart';
 
 class GameScoreWidget extends StatelessWidget {
   const GameScoreWidget({
     super.key,
-    required this.game,
+    required this.activity,
   });
 
-  final Game game;
+  final Activity activity;
 
   @override
   Widget build(BuildContext context) {
@@ -20,13 +20,13 @@ class GameScoreWidget extends StatelessWidget {
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
           const Text('Settings:'),
-          Text('  board size: ${game.settings.boardSize}'),
-          Text('  colors count: ${game.settings.colorsCount}'),
+          Text('  board size: ${activity.activitySettings.boardSize}'),
+          Text('  colors count: ${activity.activitySettings.colorsCount}'),
           const Text('Game:'),
-          Text('  isRunning: ${game.isRunning}'),
-          Text('  isFinished: ${game.isFinished}'),
-          Text('  movesCount: ${game.movesCount}'),
-          Text('  score: ${game.score}'),
+          Text('  isRunning: ${activity.isRunning}'),
+          Text('  isFinished: ${activity.isFinished}'),
+          Text('  movesCount: ${activity.movesCount}'),
+          Text('  score: ${activity.score}'),
         ],
       ),
     );
diff --git a/lib/ui/widgets/game/game_settings.dart b/lib/ui/widgets/game/game_settings.dart
deleted file mode 100644
index 783e770..0000000
--- a/lib/ui/widgets/game/game_settings.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-import 'package:flutter/material.dart';
-
-class GameSettingsWidget extends StatelessWidget {
-  const GameSettingsWidget({
-    super.key,
-  });
-
-  @override
-  Widget build(BuildContext context) {
-    return const Text('(fake settings block)');
-  }
-}
diff --git a/lib/ui/widgets/theme_card.dart b/lib/ui/widgets/theme_card.dart
deleted file mode 100644
index 18fffe0..0000000
--- a/lib/ui/widgets/theme_card.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
-
-class ThemeCard extends StatelessWidget {
-  const ThemeCard({
-    super.key,
-    required this.mode,
-    required this.icon,
-  });
-
-  final IconData icon;
-  final ThemeMode mode;
-
-  @override
-  Widget build(BuildContext context) {
-    return BlocBuilder<ApplicationThemeModeCubit, ApplicationThemeModeState>(
-        builder: (BuildContext context, ApplicationThemeModeState state) {
-      return Card(
-        elevation: 2,
-        shadowColor: Theme.of(context).colorScheme.shadow,
-        color: state.themeMode == mode
-            ? Theme.of(context).colorScheme.primary
-            : Theme.of(context).colorScheme.surface,
-        shape: const RoundedRectangleBorder(
-          borderRadius: BorderRadius.all(Radius.circular(12)),
-        ),
-        margin: const EdgeInsets.all(5),
-        child: InkWell(
-          onTap: () => BlocProvider.of<ApplicationThemeModeCubit>(context).getTheme(
-            ApplicationThemeModeState(themeMode: mode),
-          ),
-          borderRadius: const BorderRadius.all(Radius.circular(12)),
-          child: Icon(
-            icon,
-            size: 32,
-            color:
-                state.themeMode != mode ? Theme.of(context).colorScheme.primary : Colors.white,
-          ),
-        ),
-      );
-    });
-  }
-}
diff --git a/pubspec.lock b/pubspec.lock
index f45210b..1c082e2 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -113,14 +113,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.6"
-  curved_navigation_bar:
-    dependency: "direct main"
-    description:
-      name: curved_navigation_bar
-      sha256: bb4ab128fcb6f4a9f0f1f72d227db531818b20218984789777f049fcbf919279
-      url: "https://pub.dev"
-    source: hosted
-    version: "1.0.6"
   dio:
     dependency: "direct main"
     description:
@@ -325,10 +317,10 @@ packages:
     dependency: transitive
     description:
       name: path_provider
-      sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
+      sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
       url: "https://pub.dev"
     source: hosted
-    version: "2.1.4"
+    version: "2.1.5"
   path_provider_android:
     dependency: transitive
     description:
@@ -530,10 +522,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: "2735daae5150e8b1dfeb3eb0544b4d3af0061e9e82cef063adcd583bdae4306a"
+      sha256: "10169d3934549017f0ae278ccb07f828f9d6ea21573bab0fb77b0e1ef0fce454"
       url: "https://pub.dev"
     source: hosted
-    version: "5.7.0"
+    version: "5.7.2"
   xdg_directories:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index e7063fc..6985ebe 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: A random application, for testing purpose only.
 
 publish_to: "none"
 
-version: 1.2.1+70
+version: 1.3.0+71
 
 environment:
   sdk: "^3.0.0"
@@ -20,7 +20,6 @@ dependencies:
 
   # specific
   camera: ^0.11.0+2
-  curved_navigation_bar: ^1.0.3
   dio: ^5.3.3
   path: ^1.9.0
 
@@ -31,3 +30,4 @@ flutter:
   uses-material-design: true
   assets:
     - assets/translations/
+    - assets/ui/
diff --git a/resources/build_resources.sh b/resources/build_resources.sh
index 4b76d1c..774953c 100755
--- a/resources/build_resources.sh
+++ b/resources/build_resources.sh
@@ -3,3 +3,4 @@
 CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
 
 ${CURRENT_DIR}/app/build_application_resources.sh
+${CURRENT_DIR}/ui/build_ui_resources.sh
diff --git a/resources/ui/build_ui_resources.sh b/resources/ui/build_ui_resources.sh
new file mode 100755
index 0000000..f6c3f33
--- /dev/null
+++ b/resources/ui/build_ui_resources.sh
@@ -0,0 +1,144 @@
+#! /bin/bash
+
+# Check dependencies
+command -v inkscape >/dev/null 2>&1 || {
+  echo >&2 "I require inkscape but it's not installed. Aborting."
+  exit 1
+}
+command -v scour >/dev/null 2>&1 || {
+  echo >&2 "I require scour but it's not installed. Aborting."
+  exit 1
+}
+command -v optipng >/dev/null 2>&1 || {
+  echo >&2 "I require optipng but it's not installed. Aborting."
+  exit 1
+}
+
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
+BASE_DIR="$(dirname "$(dirname "${CURRENT_DIR}")")"
+ASSETS_DIR="${BASE_DIR}/assets"
+
+OPTIPNG_OPTIONS="-preserve -quiet -o7"
+IMAGE_SIZE=192
+
+#######################################################
+
+# Game images (svg files found in `images` folder)
+AVAILABLE_GAME_SVG_IMAGES=""
+AVAILABLE_GAME_PNG_IMAGES=""
+if [ -d "${CURRENT_DIR}/images" ]; then
+  AVAILABLE_GAME_SVG_IMAGES="$(find "${CURRENT_DIR}/images" -type f -name "*.svg" | awk -F/ '{print $NF}' | cut -d"." -f1 | sort)"
+  AVAILABLE_GAME_PNG_IMAGES="$(find "${CURRENT_DIR}/images" -type f -name "*.png" | awk -F/ '{print $NF}' | cut -d"." -f1 | sort)"
+fi
+
+# Skins (subfolders found in `skins` folder)
+AVAILABLE_SKINS=""
+if [ -d "${CURRENT_DIR}/skins" ]; then
+  AVAILABLE_SKINS="$(find "${CURRENT_DIR}/skins" -mindepth 1 -type d | awk -F/ '{print $NF}')"
+fi
+
+# Images per skin (svg files found recursively in `skins` folder and subfolders)
+SKIN_SVG_IMAGES=""
+SKIN_PNG_IMAGES=""
+if [ -d "${CURRENT_DIR}/skins" ]; then
+  SKIN_SVG_IMAGES="$(find "${CURRENT_DIR}/skins" -type f -name "*.svg" | awk -F/ '{print $NF}' | cut -d"." -f1 | sort | uniq)"
+  SKIN_PNG_IMAGES="$(find "${CURRENT_DIR}/skins" -type f -name "*.png" | awk -F/ '{print $NF}' | cut -d"." -f1 | sort | uniq)"
+fi
+
+#######################################################
+
+# optimize svg
+function optimize_svg() {
+  SOURCE="$1"
+
+  cp ${SOURCE} ${SOURCE}.tmp
+  scour \
+    --remove-descriptive-elements \
+    --enable-id-stripping \
+    --enable-viewboxing \
+    --enable-comment-stripping \
+    --nindent=4 \
+    --quiet \
+    -i ${SOURCE}.tmp \
+    -o ${SOURCE}
+  rm ${SOURCE}.tmp
+}
+
+# build png from svg
+function build_svg_image() {
+  SOURCE="$1"
+  TARGET="$2"
+
+  echo "Building ${TARGET}"
+
+  if [ ! -f "${SOURCE}" ]; then
+    echo "Missing file: ${SOURCE}"
+    exit 1
+  fi
+
+  optimize_svg "${SOURCE}"
+
+  mkdir -p "$(dirname "${TARGET}")"
+
+  inkscape \
+    --export-width=${IMAGE_SIZE} \
+    --export-height=${IMAGE_SIZE} \
+    --export-filename=${TARGET} \
+    "${SOURCE}"
+
+  optipng ${OPTIPNG_OPTIONS} "${TARGET}"
+}
+
+# build png from png
+function build_png_image() {
+  SOURCE="$1"
+  TARGET="$2"
+
+  echo "Building ${TARGET}"
+
+  if [ ! -f "${SOURCE}" ]; then
+    echo "Missing file: ${SOURCE}"
+    exit 1
+  fi
+
+  mkdir -p "$(dirname "${TARGET}")"
+
+  convert -resize ${IMAGE_SIZE}x${IMAGE_SIZE} "${SOURCE}" "${TARGET}"
+
+  optipng ${OPTIPNG_OPTIONS} "${TARGET}"
+}
+
+function build_images_for_skin() {
+  SKIN_CODE="$1"
+
+  # skin images
+  for SKIN_SVG_IMAGE in ${SKIN_SVG_IMAGES}; do
+    build_svg_image ${CURRENT_DIR}/skins/${SKIN_CODE}/${SKIN_SVG_IMAGE}.svg ${ASSETS_DIR}/skins/${SKIN_CODE}_${SKIN_SVG_IMAGE}.png
+  done
+  for SKIN_PNG_IMAGE in ${SKIN_PNG_IMAGES}; do
+    build_png_image ${CURRENT_DIR}/skins/${SKIN_CODE}/${SKIN_PNG_IMAGE}.png ${ASSETS_DIR}/skins/${SKIN_CODE}_${SKIN_PNG_IMAGE}.png
+  done
+}
+
+#######################################################
+
+# Delete existing generated images
+if [ -d "${ASSETS_DIR}/ui" ]; then
+  find ${ASSETS_DIR}/ui -type f -name "*.png" -delete
+fi
+if [ -d "${ASSETS_DIR}/skins" ]; then
+  find ${ASSETS_DIR}/skins -type f -name "*.png" -delete
+fi
+
+# build game images
+for GAME_SVG_IMAGE in ${AVAILABLE_GAME_SVG_IMAGES}; do
+  build_svg_image ${CURRENT_DIR}/images/${GAME_SVG_IMAGE}.svg ${ASSETS_DIR}/ui/${GAME_SVG_IMAGE}.png
+done
+for GAME_PNG_IMAGE in ${AVAILABLE_GAME_PNG_IMAGES}; do
+  build_png_image ${CURRENT_DIR}/images/${GAME_PNG_IMAGE}.png ${ASSETS_DIR}/ui/${GAME_PNG_IMAGE}.png
+done
+
+# build skins images
+for SKIN in ${AVAILABLE_SKINS}; do
+  build_images_for_skin "${SKIN}"
+done
diff --git a/resources/ui/images/button_back.svg b/resources/ui/images/button_back.svg
index 646fb03..018d8b7 100644
--- a/resources/ui/images/button_back.svg
+++ b/resources/ui/images/button_back.svg
@@ -1,46 +1,2 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   enable-background="new 0 0 100 100"
-   version="1.1"
-   viewBox="0 0 93.665 93.676"
-   xml:space="preserve"
-   id="svg2"
-   sodipodi:docname="button_back.svg"
-   inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg"><defs
-     id="defs2" /><sodipodi:namedview
-     id="namedview2"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:showpageshadow="2"
-     inkscape:pageopacity="0.0"
-     inkscape:pagecheckerboard="0"
-     inkscape:deskcolor="#d1d1d1"
-     inkscape:zoom="2.8284271"
-     inkscape:cx="13.788582"
-     inkscape:cy="69.473241"
-     inkscape:window-width="1480"
-     inkscape:window-height="987"
-     inkscape:window-x="3693"
-     inkscape:window-y="22"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg2" /><path
-     sodipodi:type="star"
-     style="fill:#ffffff;fill-opacity:1;stroke:#950e4f;stroke-width:7.28322966;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
-     id="path3"
-     inkscape:flatsided="true"
-     sodipodi:sides="3"
-     sodipodi:cx="-9.412034"
-     sodipodi:cy="-29.827261"
-     sodipodi:r1="25.983957"
-     sodipodi:r2="0.25983959"
-     sodipodi:arg1="0.62599396"
-     sodipodi:arg2="1.6731915"
-     inkscape:rounded="0"
-     inkscape:randomized="0"
-     d="m 11.644875,-14.603181 -44.769804,-4.600301 26.3688801,-36.471637 z"
-     transform="matrix(1.3783311,0.61746806,-0.61746806,1.3783311,45.198281,93.762039)" /></svg>
+<?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"><path transform="matrix(1.3783 .61747 -.61747 1.3783 45.198 93.762)" d="m11.645-14.603-44.77-4.6003 26.369-36.472z" fill="#fff" stroke="#950e4f" stroke-linecap="round" stroke-linejoin="round" stroke-width="7.2832"/></svg>
diff --git a/resources/ui/images/button_delete_saved_game.svg b/resources/ui/images/button_delete_saved_game.svg
index 2096130..c3f872e 100644
--- a/resources/ui/images/button_delete_saved_game.svg
+++ b/resources/ui/images/button_delete_saved_game.svg
@@ -1,38 +1,2 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   enable-background="new 0 0 100 100"
-   version="1.1"
-   viewBox="0 0 93.665 93.676"
-   xml:space="preserve"
-   id="svg1"
-   sodipodi:docname="button_delete_saved_game.svg"
-   inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg"><defs
-     id="defs1" /><sodipodi:namedview
-     id="namedview1"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:showpageshadow="2"
-     inkscape:pageopacity="0.0"
-     inkscape:pagecheckerboard="0"
-     inkscape:deskcolor="#d1d1d1"
-     inkscape:zoom="8.9457276"
-     inkscape:cx="46.838001"
-     inkscape:cy="46.893894"
-     inkscape:window-width="1480"
-     inkscape:window-height="987"
-     inkscape:window-x="3532"
-     inkscape:window-y="83"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg1" /><path
-     d="m76.652 23.303-3.6441 58.302c-0.28153 4.5103-4.0223 8.0241-8.5413 8.0241h-35.27c-4.5189 0-8.2598-3.5138-8.5413-8.0241l-3.6441-58.302h-5.4824c-1.7723 0-3.2093-1.437-3.2093-3.2093 0-1.773 1.437-3.2093 3.2093-3.2093h70.605c1.7723 0 3.2093 1.4363 3.2093 3.2093 0 1.7723-1.437 3.2093-3.2093 3.2093zm-6.8314 0h-45.979l3.0819 55.867c0.12535 2.268 2.0008 4.0433 4.2732 4.0433h31.268c2.2724 0 4.1478-1.7752 4.2732-4.0433zm-22.99 6.4188c1.6541 0 2.9952 1.3411 2.9952 2.9952v41.08c0 1.6541-1.3411 2.9952-2.9952 2.9952-1.6542 0-2.9952-1.3411-2.9952-2.9952v-41.08c0-1.6541 1.3411-2.9952 2.9952-2.9952zm-12.837 0c1.6756 0 3.0553 1.3181 3.1312 2.9921l1.8776 41.3c0.06665 1.4664-1.0681 2.7087-2.5345 2.7762-0.04011 0.0015-0.08024 0.0021-0.12108 0.0021-1.5595 0-2.8476-1.2193-2.9328-2.7774l-2.253-41.3c-0.08524-1.5646 1.114-2.9012 2.6779-2.9864 0.05157-0.0029 0.10317-0.0042 0.15474-0.0042zm25.675 0c1.5667 0 2.8361 1.2694 2.8361 2.8361 0 0.05156-6.87e-4 0.10317-0.0036 0.15474l-2.2416 41.088c-0.09171 1.6778-1.4786 2.991-3.1586 2.991-1.5667 0-2.8361-1.2694-2.8361-2.8361 0-0.05156 7.31e-4 -0.10315 0.0036-0.15474l2.2417-41.088c0.09172-1.6778 1.4786-2.991 3.1586-2.991zm-21.397-25.675h17.117c4.7265 0 8.5578 3.8313 8.5578 8.5578v4.2795h-34.231v-4.2795c0-4.7265 3.8313-8.5578 8.5578-8.5578zm0.42837 6.4188c-1.4184 0-2.5675 1.1491-2.5675 2.5675v3.8512h21.394v-3.8512c0-1.4184-1.1491-2.5675-2.5675-2.5675z"
-     fill="#fff"
-     fill-rule="evenodd"
-     stroke="#bd4812"
-     stroke-width=".75383"
-     id="path1"
-     style="stroke:#050200;stroke-opacity:1;stroke-width:1;stroke-dasharray:none" /></svg>
+<?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"><path d="m76.652 23.303-3.6441 58.302c-0.28153 4.5103-4.0223 8.0241-8.5413 8.0241h-35.27c-4.5189 0-8.2598-3.5138-8.5413-8.0241l-3.6441-58.302h-5.4824c-1.7723 0-3.2093-1.437-3.2093-3.2093 0-1.773 1.437-3.2093 3.2093-3.2093h70.605c1.7723 0 3.2093 1.4363 3.2093 3.2093 0 1.7723-1.437 3.2093-3.2093 3.2093zm-6.8314 0h-45.979l3.0819 55.867c0.12535 2.268 2.0008 4.0433 4.2732 4.0433h31.268c2.2724 0 4.1478-1.7752 4.2732-4.0433zm-22.99 6.4188c1.6541 0 2.9952 1.3411 2.9952 2.9952v41.08c0 1.6541-1.3411 2.9952-2.9952 2.9952-1.6542 0-2.9952-1.3411-2.9952-2.9952v-41.08c0-1.6541 1.3411-2.9952 2.9952-2.9952zm-12.837 0c1.6756 0 3.0553 1.3181 3.1312 2.9921l1.8776 41.3c0.06665 1.4664-1.0681 2.7087-2.5345 2.7762-0.04011 0.0015-0.08024 0.0021-0.12108 0.0021-1.5595 0-2.8476-1.2193-2.9328-2.7774l-2.253-41.3c-0.08524-1.5646 1.114-2.9012 2.6779-2.9864 0.05157-0.0029 0.10317-0.0042 0.15474-0.0042zm25.675 0c1.5667 0 2.8361 1.2694 2.8361 2.8361 0 0.05156-6.87e-4 0.10317-0.0036 0.15474l-2.2416 41.088c-0.09171 1.6778-1.4786 2.991-3.1586 2.991-1.5667 0-2.8361-1.2694-2.8361-2.8361 0-0.05156 7.31e-4 -0.10315 0.0036-0.15474l2.2417-41.088c0.09172-1.6778 1.4786-2.991 3.1586-2.991zm-21.397-25.675h17.117c4.7265 0 8.5578 3.8313 8.5578 8.5578v4.2795h-34.231v-4.2795c0-4.7265 3.8313-8.5578 8.5578-8.5578zm0.42837 6.4188c-1.4184 0-2.5675 1.1491-2.5675 2.5675v3.8512h21.394v-3.8512c0-1.4184-1.1491-2.5675-2.5675-2.5675z" fill="#fff" fill-rule="evenodd" stroke="#050200"/></svg>
diff --git a/resources/ui/images/button_resume_game.svg b/resources/ui/images/button_resume_game.svg
index 7b62a38..2bf9732 100644
--- a/resources/ui/images/button_resume_game.svg
+++ b/resources/ui/images/button_resume_game.svg
@@ -1,52 +1,2 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   enable-background="new 0 0 100 100"
-   version="1.1"
-   viewBox="0 0 93.665 93.676"
-   xml:space="preserve"
-   id="svg3"
-   sodipodi:docname="button_resume_game.svg"
-   inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg"><defs
-     id="defs3" /><sodipodi:namedview
-     id="namedview3"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:showpageshadow="2"
-     inkscape:pageopacity="0.0"
-     inkscape:pagecheckerboard="0"
-     inkscape:deskcolor="#d1d1d1"
-     inkscape:zoom="6.3255846"
-     inkscape:cx="42.525713"
-     inkscape:cy="46.161741"
-     inkscape:window-width="1920"
-     inkscape:window-height="1032"
-     inkscape:window-x="1600"
-     inkscape:window-y="25"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg3" /><g
-     id="g4"
-     transform="translate(-5.6180493)"><path
-       sodipodi:type="star"
-       style="fill:#ffffff;fill-opacity:1;stroke:#105ea2;stroke-width:7.28323;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
-       id="path3"
-       inkscape:flatsided="true"
-       sodipodi:sides="3"
-       sodipodi:cx="-9.412034"
-       sodipodi:cy="-29.827261"
-       sodipodi:r1="25.983957"
-       sodipodi:r2="0.25983959"
-       sodipodi:arg1="0.62599396"
-       sodipodi:arg2="1.6731915"
-       inkscape:rounded="0"
-       inkscape:randomized="0"
-       d="m 11.644875,-14.603181 -44.769804,-4.600301 26.3688801,-36.471637 z"
-       transform="matrix(-1.3783311,-0.61746806,0.61746806,-1.3783311,55.567492,-0.08603523)" /><path
-       id="path4"
-       style="fill:#ffffff;stroke:#105ea2;stroke-width:11;stroke-linecap:round;stroke-linejoin:round"
-       d="m 15.534575,12.851645 0.002,67.972712 z"
-       sodipodi:nodetypes="ccc" /></g></svg>
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 93.665 93.676" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-5.618)" fill="#fff" stroke="#105ea2" stroke-linecap="round" stroke-linejoin="round"><path transform="matrix(-1.3783 -.61747 .61747 -1.3783 55.567 -.086035)" d="m11.645-14.603-44.77-4.6003 26.369-36.472z" stroke-width="7.2832"/><path d="m15.535 12.852 2e-3 67.973z" stroke-width="11"/></g></svg>
diff --git a/resources/ui/images/button_start.svg b/resources/ui/images/button_start.svg
index 014e565..4d7634a 100644
--- a/resources/ui/images/button_start.svg
+++ b/resources/ui/images/button_start.svg
@@ -1,46 +1,2 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   enable-background="new 0 0 100 100"
-   version="1.1"
-   viewBox="0 0 93.665 93.676"
-   xml:space="preserve"
-   id="svg3"
-   sodipodi:docname="button_start.svg"
-   inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg"><defs
-     id="defs3" /><sodipodi:namedview
-     id="namedview3"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:showpageshadow="2"
-     inkscape:pageopacity="0.0"
-     inkscape:pagecheckerboard="0"
-     inkscape:deskcolor="#d1d1d1"
-     inkscape:zoom="3.1627923"
-     inkscape:cx="-9.4852892"
-     inkscape:cy="1.8970578"
-     inkscape:window-width="1920"
-     inkscape:window-height="1032"
-     inkscape:window-x="1600"
-     inkscape:window-y="25"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg3" /><path
-     sodipodi:type="star"
-     style="fill:#ffffff;fill-opacity:1;stroke:#105ea2;stroke-width:7.28323;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
-     id="path3"
-     inkscape:flatsided="true"
-     sodipodi:sides="3"
-     sodipodi:cx="-9.412034"
-     sodipodi:cy="-29.827261"
-     sodipodi:r1="25.983957"
-     sodipodi:r2="0.25983959"
-     sodipodi:arg1="0.62599396"
-     sodipodi:arg2="1.6731915"
-     inkscape:rounded="0"
-     inkscape:randomized="0"
-     d="m 11.644875,-14.603181 -44.769804,-4.600301 26.3688801,-36.471637 z"
-     transform="matrix(-1.3783311,-0.61746806,0.61746806,-1.3783311,46.954337,-0.08603523)" /></svg>
+<?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"><path transform="matrix(-1.3783 -.61747 .61747 -1.3783 46.954 -.086035)" d="m11.645-14.603-44.77-4.6003 26.369-36.472z" fill="#fff" stroke="#105ea2" stroke-linecap="round" stroke-linejoin="round" stroke-width="7.2832"/></svg>
-- 
GitLab