diff --git a/frontend/src/js/clue_payloads.ts b/frontend/src/js/clue_payloads.ts
index 4c7bc35c869f08d6508b73e3251df3cb0488cf21..c6488a96f6cd3e56677b9273dfbbb3e54e50a4be 100644
--- a/frontend/src/js/clue_payloads.ts
+++ b/frontend/src/js/clue_payloads.ts
@@ -1,6 +1,7 @@
 import "phaser";
 
 import { Word } from "../../../backend/src/types";
+import TEXT_STYLES from "./text_styles";
 
 interface CluePayload {
   baseHeight: number;
@@ -10,55 +11,12 @@ interface CluePayload {
 
 //=[ Text clues ]===============================================================
 
-import { FONTS } from "./assets";
-
-const GERMAN_ALPHABET =
-  "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ" + "abcdefghijklmnopqrstuvwxyzäöüß";
-
-export const TEXT_STYLE: {
-  [key: string]: Phaser.Types.GameObjects.Text.TextStyle;
-} = {
-  TYPEWRITER: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-    testString: GERMAN_ALPHABET,
-  },
-  TRAINING: {
-    fontFamily: FONTS.FRAK,
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-    testString: GERMAN_ALPHABET,
-  },
-  MONO_NEWSPAPER: {
-    fontFamily: FONTS.MONO,
-    color: "#333333",
-    stroke: "#666666",
-    strokeThickness: 4,
-    testString: GERMAN_ALPHABET,
-    backgroundColor: "#aaaaaa",
-    padding: { x: 8 },
-  },
-  FRAK_NEWSPAPER: {
-    fontFamily: FONTS.FRAK,
-    color: "#333333",
-    stroke: "#666666",
-    strokeThickness: 4,
-    testString: GERMAN_ALPHABET,
-    backgroundColor: "#aaaaaa",
-    padding: { x: 8 },
-  },
-};
-
 export class TextCluePayload
   extends Phaser.GameObjects.Text
   implements CluePayload
 {
   baseHeight: number;
-  textStyle = TEXT_STYLE.TYPEWRITER;
+  textStyle = TEXT_STYLES.CLUE_DEFAULT;
 
   constructor(scene: Phaser.Scene, baseHeight: number) {
     super(scene, 0, 0, "", TextCluePayload.prototype.textStyle);
diff --git a/frontend/src/js/game_over_scene.ts b/frontend/src/js/game_over_scene.ts
index 802f9b8615f1aab54f9c0af70b6150b7c48c08c6..f02c99347696a548389a5db07dbe50047c6d9567 100644
--- a/frontend/src/js/game_over_scene.ts
+++ b/frontend/src/js/game_over_scene.ts
@@ -1,9 +1,7 @@
 import "phaser";
-import { FONTS } from "./assets";
 import BackgroundScene from "./background_scene";
 import { formatTime, ICONS } from "./hud";
-
-const BUTTON_HIGHLIGHT_COLOR = "darkorange";
+import TEXT_STYLES from "./text_styles";
 
 const SS_KEYS = {
   BEST_WORDS: "OETZIT/BEST_WORDS",
@@ -11,19 +9,6 @@ const SS_KEYS = {
   BEST_TIMER: "OETZIT/BEST_TIMER",
 };
 
-const TEXT_STYLE: {
-  [key: string]: Phaser.Types.GameObjects.Text.TextStyle;
-} = {
-  BUTTON: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
-  },
-};
-
 export default class GameOverScene extends Phaser.Scene {
   music!: Phaser.Sound.BaseSound;
   continueButton!: Phaser.GameObjects.Text;
@@ -87,10 +72,10 @@ export default class GameOverScene extends Phaser.Scene {
   drawTitle() {
     const text = "GAME OVER";
     const title = this.add.text(0, 0, text, {
+      ...TEXT_STYLES.BASE,
       fontSize: "48px",
-      fontFamily: FONTS.MONO,
-      fontStyle: "bold",
       color: "#ff0000",
+      testString: text,
     });
     title.setOrigin(0.5, 0);
     title.setPosition(
@@ -102,11 +87,9 @@ export default class GameOverScene extends Phaser.Scene {
   drawSubtitle() {
     const text = `You contributed\n${ICONS.HEALTH} to our research! ${ICONS.HEALTH}\nThank you!`; //
     const subtitle = this.add.text(0, 0, text, {
+      ...TEXT_STYLES.BASE,
       fontSize: "28px",
-      fontFamily: FONTS.MONO,
-      fontStyle: "bold",
       color: "#aaff00",
-      align: "center",
       testString: text,
     });
     subtitle.setOrigin(0.5, 0);
@@ -141,10 +124,8 @@ export default class GameOverScene extends Phaser.Scene {
   ) {
     const text = this.formatResult(words, score, time);
     const title = this.add.text(0, 0, text, {
+      ...TEXT_STYLES.BASE,
       fontSize: "28px",
-      fontFamily: FONTS.MONO,
-      fontStyle: "bold",
-      color: "#ffffff",
       testString: text,
     });
     title.setOrigin(0.5, 0);
@@ -154,10 +135,8 @@ export default class GameOverScene extends Phaser.Scene {
     );
     if (this.beatScore || this.beatTimer || this.beatWords) {
       const newPB = this.add.text(0, 0, "You set new records!", {
+        ...TEXT_STYLES.BASE,
         fontSize: "28px",
-        fontFamily: FONTS.MONO,
-        fontStyle: "bold",
-        color: "#ffffff",
         testString: text,
       });
       newPB.setOrigin(0.5, 0);
@@ -173,17 +152,19 @@ export default class GameOverScene extends Phaser.Scene {
     const text = `${verb} to continue`;
     this.continueButton = this.add
       .text(this.cameras.main.centerX, this.cameras.main.height * 0.9, text, {
-        ...TEXT_STYLE.BUTTON,
+        ...TEXT_STYLES.BUTTON,
         fontSize: "32px",
       })
       .setOrigin(0.5, 1)
       .setPadding(4)
       .setInteractive({ useHandCursor: true })
       .on("pointerover", () =>
-        this.continueButton.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }),
+        this.continueButton.setStyle({
+          stroke: TEXT_STYLES.BUTTON_HOVER.stroke,
+        }),
       )
       .on("pointerout", () =>
-        this.continueButton.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }),
+        this.continueButton.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }),
       );
   }
 
diff --git a/frontend/src/js/hud.ts b/frontend/src/js/hud.ts
index 7f41876cf110f7268be1774ac064e6abb8f60378..7dc8dd9255a6d2dd6d90226adf0921e5f8375869 100644
--- a/frontend/src/js/hud.ts
+++ b/frontend/src/js/hud.ts
@@ -1,4 +1,4 @@
-import { FONTS } from "./assets";
+import TEXT_STYLES from "./text_styles";
 
 export const ICONS = {
   SCORE: "️⭐️",
@@ -8,22 +8,6 @@ export const ICONS = {
 
 export const THIN_SPACE = "\u2009";
 
-const STATS_BASE_TEXT_STYLE = {
-  fontFamily: FONTS.MONO,
-  fontStyle: "bold",
-  color: "white",
-  testString: `${Object.values(ICONS).join("")}1234567890:.`,
-  stroke: "black",
-  strokeThickness: 4,
-} as Phaser.Types.GameObjects.Text.TextStyle;
-
-const INPUT_BASE_TEXT_STYLE = {
-  fontFamily: FONTS.MONO,
-  fontStyle: "bold",
-  color: "white",
-  testString: `ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖẞabcdefghijklmnopqrstuvwxyzäüöß `,
-} as Phaser.Types.GameObjects.Text.TextStyle;
-
 interface HudOptions {
   statsPadding: number;
   statsFontSize: string;
@@ -81,7 +65,8 @@ export default class HUD {
 
   inputTextStyle(): Phaser.Types.GameObjects.Text.TextStyle {
     return {
-      ...INPUT_BASE_TEXT_STYLE,
+      ...TEXT_STYLES.HUD_INPUT,
+      testString: `ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖẞabcdefghijklmnopqrstuvwxyzäüöß`,
       fontSize: this.options.inputFontSize,
       padding: {
         x: this.options.inputPadding,
@@ -92,7 +77,8 @@ export default class HUD {
 
   statsTextStyle(): Phaser.Types.GameObjects.Text.TextStyle {
     return {
-      ...STATS_BASE_TEXT_STYLE,
+      ...TEXT_STYLES.HUD_STAT,
+      testString: `${Object.values(ICONS).join("")}1234567890:.`,
       fontSize: this.options.statsFontSize,
       padding: {
         x: this.options.statsPadding,
diff --git a/frontend/src/js/leaderboard_scene.ts b/frontend/src/js/leaderboard_scene.ts
index 244d64ae9042a332d36abaea9e684f1e6dee5c0c..34697b8445f9b51748a9aba1238eb97c4fb64f3f 100644
--- a/frontend/src/js/leaderboard_scene.ts
+++ b/frontend/src/js/leaderboard_scene.ts
@@ -1,5 +1,4 @@
 import "phaser";
-import { FONTS } from "./assets";
 
 import { uniqueNamesGenerator, names } from "unique-names-generator";
 import backend from "./backend";
@@ -9,42 +8,10 @@ import {
 } from "../../../backend/src/types";
 import Game from "./game";
 import { sha256 } from "./utils";
+import TEXT_STYLES from "./text_styles";
 
 const MEDALS = ["🥇", "🥈", "🥉"];
 
-const BUTTON_HIGHLIGHT_COLOR = "darkorange";
-
-const TEXT_STYLE: {
-  [key: string]: Phaser.Types.GameObjects.Text.TextStyle;
-} = {
-  LIST: {
-    fontSize: "28px",
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "#ffffff",
-    stroke: "black",
-    strokeThickness: 4,
-  },
-  MESSAGE: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "#ffffff",
-    fontSize: "32px",
-    testString:
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890",
-    align: "center",
-  },
-  BUTTON: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
-    fontSize: "32px",
-  },
-};
-
 export default class LeaderboardScene extends Phaser.Scene {
   game!: Game;
   music!: Phaser.Sound.BaseSound;
@@ -87,12 +54,13 @@ export default class LeaderboardScene extends Phaser.Scene {
 
   async createRankings() {
     const renderedRankings = this.renderRankings(this.leaderboardView);
-
+    const fontSize = Math.min(this.cameras.main.height * 0.25, 24);
     this.rankings = this.add
       .text(0, 0, renderedRankings, {
-        ...TEXT_STYLE.LIST,
+        ...TEXT_STYLES.BASE,
         testString: renderedRankings,
       })
+      .setFontSize(fontSize)
       .setOrigin(0.5, 0)
       .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.1);
   }
@@ -152,14 +120,15 @@ export default class LeaderboardScene extends Phaser.Scene {
 
   createMessage() {
     const renderedMessage = this.renderMessage();
+    const fontSize = Math.min(this.cameras.main.height * 0.25, 24);
     this.message = this.add
-      .text(
+      .text(0, 0, renderedMessage, TEXT_STYLES.BASE)
+      .setOrigin(0.5, 0)
+      .setFontSize(fontSize)
+      .setPosition(
         this.cameras.main.centerX,
         this.rankings.getBounds().bottom + 32,
-        renderedMessage,
-        TEXT_STYLE.MESSAGE,
-      )
-      .setOrigin(0.5, 0);
+      );
   }
 
   renderMessage() {
@@ -171,20 +140,19 @@ export default class LeaderboardScene extends Phaser.Scene {
   }
 
   createBackBtn() {
-    const verb = this.game.device.os.desktop ? "Click" : "Tap";
-    const text = `${verb} to continue`;
+    const text = "Back to menu";
+    const fontSize = Math.min(this.cameras.main.height * 0.25, 32);
     this.backBtn = this.add
-      .text(this.cameras.main.centerX, this.cameras.main.height * 0.9, text, {
-        ...TEXT_STYLE.BUTTON,
-      })
+      .text(0, 0, text, TEXT_STYLES.BUTTON)
       .setOrigin(0.5, 1)
-      .setPadding(4)
+      .setFontSize(fontSize)
+      .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.95)
       .setInteractive({ useHandCursor: true })
       .on("pointerover", () =>
-        this.backBtn.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }),
+        this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }),
       )
       .on("pointerout", () =>
-        this.backBtn.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }),
+        this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }),
       );
   }
 
diff --git a/frontend/src/js/loading_scene.ts b/frontend/src/js/loading_scene.ts
index 01ad60d8be04876f547721a448d89bf701c4a1de..f714ac392d158c9dc8abee4fe89bf140b7deb4cf 100644
--- a/frontend/src/js/loading_scene.ts
+++ b/frontend/src/js/loading_scene.ts
@@ -1,13 +1,13 @@
 import "phaser";
 import {
   BackgroundImages,
-  FONTS,
   MusicEffects,
   RexWebFontLoaderConfig,
   RexWebFontLoaderPluginFileConfig,
   SoundEffects,
   SpriteSheets,
 } from "./assets";
+import TEXT_STYLES from "./text_styles";
 
 export default class LoadingScene extends Phaser.Scene {
   progressBar!: Phaser.GameObjects.Graphics;
@@ -71,12 +71,7 @@ export default class LoadingScene extends Phaser.Scene {
       origin: 0.5,
       text: "LOADING: 0%",
       style: {
-        fontFamily: FONTS.MONO,
-        fontStyle: "bold",
-        fontSize: "32px",
-        color: "white",
-        stroke: "black",
-        strokeThickness: 4,
+        ...TEXT_STYLES.LOADING,
         testString: "LOADING: 0123456789%",
       },
     });
diff --git a/frontend/src/js/pause_scene.ts b/frontend/src/js/pause_scene.ts
index 97b015c51944b9684ebf2da3a442c78e2dc180a6..919a56b61138fb5f5cb18fa56d6bc53d8298a2fb 100644
--- a/frontend/src/js/pause_scene.ts
+++ b/frontend/src/js/pause_scene.ts
@@ -1,5 +1,5 @@
 import "phaser";
-import { FONTS } from "./assets";
+import TEXT_STYLES from "./text_styles";
 
 export default class PauseScene extends Phaser.Scene {
   enabled = true;
@@ -31,20 +31,15 @@ export default class PauseScene extends Phaser.Scene {
 
   drawTitle() {
     const text = "PAUSED";
-    const title = this.add.text(0, 0, text, {
-      fontFamily: FONTS.MONO,
-      fontSize: "64px",
-      fontStyle: "bold",
-      color: "white",
-      stroke: "black",
-      strokeThickness: 4,
-      testString: text,
-    });
-    title.setOrigin(0.5, 1);
-    title.setPosition(
-      this.cameras.main.width * 0.5,
-      this.cameras.main.height * 0.475,
-    );
+    const fontSize = Math.min(this.cameras.main.height * 0.25, 64);
+    this.add
+      .text(0, 0, text, TEXT_STYLES.BASE)
+      .setFontSize(fontSize)
+      .setOrigin(0.5, 1)
+      .setPosition(
+        this.cameras.main.width * 0.5,
+        this.cameras.main.height * 0.475,
+      );
   }
 
   drawCTA() {
@@ -54,21 +49,15 @@ export default class PauseScene extends Phaser.Scene {
       ? "ESC"
       : "tap";
     const text = `TAKE A BREATH\n${verb} to resume`;
-    const title = this.add.text(0, 0, text, {
-      fontFamily: FONTS.MONO,
-      fontSize: "32px",
-      fontStyle: "bold",
-      color: "white",
-      stroke: "black",
-      strokeThickness: 4,
-      testString: text,
-      align: "center",
-    });
-    title.setOrigin(0.5, 0);
-    title.setPosition(
-      this.cameras.main.width * 0.5,
-      this.cameras.main.height * 0.525,
-    );
+    const fontSize = Math.min(this.cameras.main.height * 0.125, 32);
+    this.add
+      .text(0, 0, text, TEXT_STYLES.BASE)
+      .setFontSize(fontSize)
+      .setOrigin(0.5, 0)
+      .setPosition(
+        this.cameras.main.width * 0.5,
+        this.cameras.main.height * 0.525,
+      );
   }
 
   focusPause(manual: boolean) {
diff --git a/frontend/src/js/rewards_scene.ts b/frontend/src/js/rewards_scene.ts
index f35fd2053be349f16262f5bdb2ff81197618a6f2..e9f3b8245dd4ec070e7013a4944ef23003541c93 100644
--- a/frontend/src/js/rewards_scene.ts
+++ b/frontend/src/js/rewards_scene.ts
@@ -1,40 +1,15 @@
 import "phaser";
-import { FONTS } from "./assets";
 
 import backend from "./backend";
 import Game from "./game";
 import PauseScene from "./pause_scene";
-
-const BUTTON_HIGHLIGHT_COLOR = "darkorange";
+import TEXT_STYLES from "./text_styles";
 
 // NOTE: see https://stackoverflow.com/a/26989421
 const RFC_5322 = new RegExp(
   /^([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])$/,
 );
 
-const TEXT_STYLE: {
-  [key: string]: Phaser.Types.GameObjects.Text.TextStyle;
-} = {
-  MESSAGE: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "#ffffff",
-    fontSize: "32px",
-    testString:
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890",
-    align: "center",
-  },
-  BUTTON: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
-    fontSize: "32px",
-  },
-};
-
 export default class RewardsScene extends Phaser.Scene {
   game!: Game;
   music!: Phaser.Sound.BaseSound;
@@ -60,73 +35,75 @@ export default class RewardsScene extends Phaser.Scene {
   }
 
   createExplanation() {
-    const text = "We reward top players weekly! Enter your email to compete:";
+    const text = "We reward top players weekly!\nEnter your email to compete:";
+    const fontSize = Math.min(this.cameras.main.height * 0.125, 24);
     this.explanation = this.add
-      .text(this.cameras.main.centerX, this.cameras.main.height * 0.1, text, {
-        ...TEXT_STYLE.MESSAGE,
-        testString: text,
-        wordWrap: { width: this.cameras.main.width * 0.6 },
-      })
-      .setOrigin(0.5, 0);
+      .text(0, 0, text, TEXT_STYLES.BASE)
+      .setFontSize(fontSize)
+      .setOrigin(0.5, 0)
+      .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.05);
   }
 
   createMailBox() {
     this.mailBox = this.add
-      .text(this.cameras.main.centerX, this.cameras.main.centerY, "", {
-        ...TEXT_STYLE.BUTTON,
-        padding: { x: 16, y: 16 },
-      })
+      .text(
+        this.cameras.main.centerX,
+        this.cameras.main.centerY,
+        "",
+        TEXT_STYLES.BUTTON,
+      )
       .setOrigin(0.5, 1)
+      .setPadding(16)
       .setInteractive({ useHandCursor: true })
       .on("pointerover", () =>
-        this.mailBox.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }),
+        this.mailBox.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }),
       )
       .on("pointerout", () =>
-        this.mailBox.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }),
+        this.mailBox.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }),
       );
     this.refreshMailBox();
   }
 
   createPrivacyNotice() {
     const text =
-      "By filling the input you agree to our privacy policy. You can read it HERE 🖋️🤓";
+      "By filling the input you agree to our privacy policy.\nYou can read it HERE 🖋️🤓";
+    const fontSize = Math.min(this.cameras.main.height * 0.125, 16);
     this.privacy = this.add
       .text(
         this.cameras.main.centerX,
         this.mailBox.getBounds().bottom + 16,
         text,
         {
-          ...TEXT_STYLE.BUTTON,
-          fontSize: "24px",
+          ...TEXT_STYLES.BUTTON,
           testString: text,
-          wordWrap: { width: this.cameras.main.width * 0.6 },
           align: "center",
         },
       )
+      .setFontSize(fontSize)
       .setOrigin(0.5, 0)
       .setInteractive({ useHandCursor: true })
       .on("pointerover", () =>
-        this.privacy.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }),
+        this.privacy.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }),
       )
       .on("pointerout", () =>
-        this.privacy.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }),
+        this.privacy.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }),
       );
   }
 
   createBackBtn() {
     const text = "Back to menu";
+    const fontSize = Math.min(this.cameras.main.height * 0.25, 32);
     this.backBtn = this.add
-      .text(this.cameras.main.centerX, this.cameras.main.height * 0.9, text, {
-        ...TEXT_STYLE.BUTTON,
-      })
+      .text(0, 0, text, TEXT_STYLES.BUTTON)
+      .setFontSize(fontSize)
       .setOrigin(0.5, 1)
-      .setPadding(4)
+      .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.95)
       .setInteractive({ useHandCursor: true })
       .on("pointerover", () =>
-        this.backBtn.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }),
+        this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }),
       )
       .on("pointerout", () =>
-        this.backBtn.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }),
+        this.backBtn.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }),
       );
   }
 
diff --git a/frontend/src/js/text_styles.ts b/frontend/src/js/text_styles.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bd0679a7fe38162093d91e0bc4881d2b3b9c281e
--- /dev/null
+++ b/frontend/src/js/text_styles.ts
@@ -0,0 +1,95 @@
+import { FONTS } from "./assets";
+
+const TEXT_STYLES: {
+  [key: string]: Phaser.Types.GameObjects.Text.TextStyle;
+} = {
+  BASE: {
+    align: "center",
+    color: "white",
+    fontFamily: FONTS.MONO,
+    fontStyle: "bold",
+    stroke: "black",
+    strokeThickness: 8,
+    testString:
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?;:,.-()",
+  },
+  BUTTON: {
+    color: "white",
+    fontFamily: FONTS.MONO,
+    fontSize: "32px",
+    fontStyle: "bold",
+    stroke: "black",
+    strokeThickness: 8,
+    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+    padding: { x: 8, y: 8 },
+  },
+  BUTTON_HOVER: {
+    stroke: "darkorange",
+  },
+  CHEATSHEET: {
+    color: "#ffffff",
+    fontFamily: FONTS.FRAK,
+    stroke: "black",
+    strokeThickness: 4,
+  },
+  CLUE_DEFAULT: {
+    color: "white",
+    fontFamily: FONTS.MONO,
+    fontStyle: "bold",
+    stroke: "black",
+    strokeThickness: 8,
+    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞabcdefghijklmnopqrstuvwxyzäöüß",
+  },
+  CLUE_NEWSPAPER_FRAK: {
+    backgroundColor: "#aaaaaa",
+    color: "#333333",
+    fontFamily: FONTS.FRAK,
+    padding: {
+      x: 8,
+    },
+    stroke: "#666666",
+    strokeThickness: 4,
+    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞabcdefghijklmnopqrstuvwxyzäöüß",
+  },
+  CLUE_NEWSPAPER_MONO: {
+    backgroundColor: "#aaaaaa",
+    color: "#333333",
+    fontFamily: FONTS.MONO,
+    padding: {
+      x: 8,
+    },
+    stroke: "#666666",
+    strokeThickness: 4,
+    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞabcdefghijklmnopqrstuvwxyzäöüß",
+  },
+  HUD_INPUT: {
+    color: "white",
+    fontFamily: FONTS.MONO,
+    fontStyle: "bold",
+  },
+  HUD_STAT: {
+    color: "white",
+    fontFamily: FONTS.MONO,
+    fontStyle: "bold",
+    stroke: "black",
+    strokeThickness: 4,
+  },
+  LOADING: {
+    color: "white",
+    fontFamily: FONTS.MONO,
+    fontSize: "32px",
+    fontStyle: "bold",
+    stroke: "black",
+    strokeThickness: 4,
+  },
+  VERSION_TAG: {
+    color: "#888888",
+    fontFamily: FONTS.MONO,
+    fontSize: "16px",
+    fontStyle: "bold",
+    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.",
+    padding: { x: 8, y: 8 },
+  },
+};
+
+export default TEXT_STYLES;
diff --git a/frontend/src/js/tutorial_scene.ts b/frontend/src/js/tutorial_scene.ts
index c029a6ce1ac6c7e2d3ed53ba073c169e924d1ffa..106fc673bcdef7869677dcf2867fa04c01bcbbc9 100644
--- a/frontend/src/js/tutorial_scene.ts
+++ b/frontend/src/js/tutorial_scene.ts
@@ -1,26 +1,12 @@
 import "phaser";
 
-import { FONTS } from "./assets";
 import MainScene, { InputStatus } from "./main_scene";
 import Spear from "./spear";
+import TEXT_STYLES from "./text_styles";
 
 import { STEPS } from "./tutorial_steps";
 import { nthFibonacci } from "./utils";
 
-const BUTTON_HIGHLIGHT_COLOR = "darkorange";
-
-const TEXT_STYLE: {
-  [key: string]: Phaser.Types.GameObjects.Text.TextStyle;
-} = {
-  TUTORIAL: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-  },
-};
-
 export interface TutorialStep {
   setup: (scene: TutorialScene) => void;
   teardown: (scene: TutorialScene) => void;
@@ -72,17 +58,15 @@ export default class TutorialScene extends MainScene {
   }
 
   createText(options: CreateTextOptions) {
+    const fontSize = Math.min(this.cameras.main.width * 0.125, 32);
     const text = this.add
       .text(
         options.positionX ?? this.cameras.main.centerX,
         options.positionY ?? this.cameras.main.centerY,
         options.text,
-        {
-          ...TEXT_STYLE.TUTORIAL,
-          fontSize: `${Math.min(this.cameras.main.width * 0.125, 32)}px`,
-          align: "center",
-        },
+        TEXT_STYLES.BASE,
       )
+      .setFontSize(fontSize)
       .setOrigin(options.originX ?? 0.5, options.originY ?? 0.5)
       .setPadding(16);
 
@@ -90,10 +74,10 @@ export default class TutorialScene extends MainScene {
       text
         .setInteractive({ useHandCursor: true })
         .on("pointerover", () =>
-          text.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }),
+          text.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }),
         )
         .on("pointerout", () =>
-          text.setStyle({ stroke: TEXT_STYLE.TUTORIAL.stroke }),
+          text.setStyle({ stroke: TEXT_STYLES.BASE.stroke }),
         )
         .on("pointerup", () => this.nextStep());
     return text;
diff --git a/frontend/src/js/tutorial_steps.ts b/frontend/src/js/tutorial_steps.ts
index 72995cb1825fcd5778ce4ec2d82c251f73f33e5b..b98a5d3007479ce0f57d373a30550bb544b5652d 100644
--- a/frontend/src/js/tutorial_steps.ts
+++ b/frontend/src/js/tutorial_steps.ts
@@ -4,8 +4,8 @@ import TutorialScene, { TutorialStep } from "./tutorial_scene";
 import Critter from "./critter";
 import Spear from "./spear";
 import Foe from "./foe";
-import { FONTS } from "./assets";
-import { TextCluePayload, TEXT_STYLE } from "./clue_payloads";
+import { TextCluePayload } from "./clue_payloads";
+import TEXT_STYLES from "./text_styles";
 
 interface TrialRoundOptions {
   scene: TutorialScene;
@@ -215,10 +215,9 @@ export const STEPS: TutorialStep[] = [
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: `Nice job ${scene.userName}! 👑👍\nNow, the real thing...`,
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        `Nice job ${scene.userName}! 👑👍\nNow, the real thing...`,
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
@@ -226,7 +225,7 @@ export const STEPS: TutorialStep[] = [
   {
     setup: (scene) => {
       scene.setTypewriterEnabled(true);
-      TextCluePayload.prototype.textStyle = TEXT_STYLE.MONO_NEWSPAPER;
+      TextCluePayload.prototype.textStyle = TEXT_STYLES.CLUE_NEWSPAPER_MONO;
       trialRound({
         scene: scene,
         words: ["i", "am", scene.userName],
@@ -244,20 +243,18 @@ export const STEPS: TutorialStep[] = [
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: `↖️ 💪🏅\nGreat! You scored\n${scene.score} points`,
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        `↖️ 💪🏅\nGreat! You scored\n${scene.score} points`,
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: "Speed and good\nCapiTaliZation\nare worth more",
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        "Speed and good\nCapiTaliZation\nare worth more",
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
@@ -265,7 +262,7 @@ export const STEPS: TutorialStep[] = [
   {
     setup: (scene) => {
       scene.setTypewriterEnabled(true);
-      TextCluePayload.prototype.textStyle = TEXT_STYLE.MONO_NEWSPAPER;
+      TextCluePayload.prototype.textStyle = TEXT_STYLES.CLUE_NEWSPAPER_MONO;
       trialRound({
         scene: scene,
         words: "no way you will catch all of these lol".split(" "),
@@ -283,40 +280,36 @@ export const STEPS: TutorialStep[] = [
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: "Words glow red when\nÖtzi is in danger\n🅰️⚠️",
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        "Words glow red when\nÖtzi is in danger\n🅰️⚠️",
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: "Longer words are worth\n(and will hurt) more\n🐘⚠️",
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        "Longer words are worth\n(and will hurt) more\n🐘⚠️",
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: "⏲️ ⬆️ ⚠️\nAlso, as time passes,\nthings will get harder",
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        "⏲️ ⬆️ ⚠️\nAlso, as time passes,\nthings will get harder",
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: "By the way, we'll\nuse Fraktur script!\n😖❓",
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        "By the way, we'll\nuse Fraktur script!\n😖❓",
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
@@ -363,12 +356,9 @@ export const STEPS: TutorialStep[] = [
             (p + h) * j + p + h * 0.5,
             letter + letter.toLocaleLowerCase(),
             {
-              fontFamily: FONTS.FRAK,
+              ...TEXT_STYLES.CHEATSHEET,
               fontSize: `${h / 1.4}px`,
               testString: alphabet + alphabet.toLowerCase(),
-              color: "#ffffff",
-              stroke: "black",
-              strokeThickness: 4,
             },
           )
           .setOrigin(0.5, 0.5);
@@ -379,10 +369,9 @@ export const STEPS: TutorialStep[] = [
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: "Yup, that's a handful.\nBrace yourself...\n😅😱",
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        "Yup, that's a handful.\nBrace yourself...\n😅😱",
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
@@ -390,10 +379,9 @@ export const STEPS: TutorialStep[] = [
   {
     setup: (scene) => {
       const verb = scene.game.device.os.desktop ? "hit ESC" : "tap twice";
-      const text = scene.createText({
-        text: `Oh! And remember:\n${verb} to pause\n🙏⏸️`,
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        `Oh! And remember:\n${verb} to pause\n🙏⏸️`,
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
@@ -402,7 +390,7 @@ export const STEPS: TutorialStep[] = [
     setup: (scene) => {
       scene.setTypewriterEnabled(true);
       scene.tapoutEnabled = true;
-      TextCluePayload.prototype.textStyle = TEXT_STYLE.FRAK_NEWSPAPER;
+      TextCluePayload.prototype.textStyle = TEXT_STYLES.CLUE_NEWSPAPER_FRAK;
       trialRound({
         scene: scene,
         words: "Üben von Xylophon und Querflöte ist ja zweckmäßig".split(" "),
@@ -425,20 +413,18 @@ export const STEPS: TutorialStep[] = [
         "Pretty good!\n😊🥈", // 3 4 5
         "Very impressive!\n🤩🥇", // 6 7 8
       ][Math.floor((3 * scene.acceptedWords) / (8 + 1))];
-      const text = scene.createText({
-        text: `You got ${scene.acceptedWords} out of 8.\n${comment}`,
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        `You got ${scene.acceptedWords} out of 8.\n${comment}`,
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
   },
   {
     setup: (scene) => {
-      const text = scene.createText({
-        text: `That's it, ${scene.userName}.\nTime to play!\n😋🕹️`,
-        positionY: scene.uiDimensions.cluesBounds.centerY,
-      });
+      const text = scene.createSimpleText(
+        `That's it, ${scene.userName}.\nTime to play!\n😋🕹️`,
+      );
       scene.bucket.push(text);
     },
     teardown: (scene) => scene.emptyBucket(),
diff --git a/frontend/src/js/welcome_scene.ts b/frontend/src/js/welcome_scene.ts
index ce2bf28ef9f636af8c21daf7df87585639c05691..c09963387e1f93ea454d4081e2905d573487dc9d 100644
--- a/frontend/src/js/welcome_scene.ts
+++ b/frontend/src/js/welcome_scene.ts
@@ -1,34 +1,5 @@
 import "phaser";
-import { FONTS } from "./assets";
-
-const BUTTON_HIGHLIGHT_COLOR = "darkorange";
-
-const TEXT_STYLE: {
-  [key: string]: Phaser.Types.GameObjects.Text.TextStyle;
-} = {
-  TITLE: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-  },
-  BUTTON: {
-    fontFamily: FONTS.MONO,
-    fontStyle: "bold",
-    color: "white",
-    stroke: "black",
-    strokeThickness: 8,
-    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
-  },
-  VERSION: {
-    fontFamily: FONTS.MONO,
-    fontSize: "16px",
-    fontStyle: "bold",
-    color: "#888888",
-    testString: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.",
-  },
-};
+import TEXT_STYLES from "./text_styles";
 
 export default class WelcomeScene extends Phaser.Scene {
   music!: Phaser.Sound.BaseSound;
@@ -70,37 +41,35 @@ export default class WelcomeScene extends Phaser.Scene {
   }
 
   createMainButton(text: string, index: number) {
-    const size = Math.min(this.cameras.main.width * 0.125, 48);
+    const fontSize = Math.min((this.cameras.main.height * 0.5) / 4 / 1.4, 48);
     const button = this.add
       .text(
         this.cameras.main.centerX,
-        this.cameras.main.centerY + index * size * 1.4,
+        this.cameras.main.centerY + index * fontSize * 1.4,
         text,
-        {
-          ...TEXT_STYLE.BUTTON,
-          fontSize: `${size}px`,
-        },
+        TEXT_STYLES.BUTTON,
       )
-      .setOrigin(0.5, 0.5)
-      .setPadding(4)
+      .setFontSize(fontSize)
+      .setOrigin(0.5, 1)
       .setInteractive({ useHandCursor: true })
       .on("pointerover", () =>
-        button.setStyle({ stroke: BUTTON_HIGHLIGHT_COLOR }),
+        button.setStyle({ stroke: TEXT_STYLES.BUTTON_HOVER.stroke }),
       )
       .on("pointerout", () =>
-        button.setStyle({ stroke: TEXT_STYLE.BUTTON.stroke }),
+        button.setStyle({ stroke: TEXT_STYLES.BUTTON.stroke }),
       );
     return button;
   }
 
   createTitleText() {
     const text = "ÖTZIT!";
+    const fontSize = Math.min(this.cameras.main.height * 0.25, 128);
     this.titleText = this.add
       .text(0, 0, text, {
-        ...TEXT_STYLE.TITLE,
-        fontSize: `${Math.min(this.cameras.main.width * 0.125, 128)}px`,
+        ...TEXT_STYLES.BASE,
         testString: text,
       })
+      .setFontSize(fontSize)
       .setOrigin(0.5, 1)
       .setPosition(this.cameras.main.centerX, this.cameras.main.height * 0.3);
   }
@@ -108,9 +77,8 @@ export default class WelcomeScene extends Phaser.Scene {
   createVersionText() {
     const text = process.env.APP_VERSION || "unknown";
     this.versionText = this.add
-      .text(0, 0, text.toUpperCase(), TEXT_STYLE.VERSION)
+      .text(0, 0, text.toUpperCase(), TEXT_STYLES.VERSION_TAG)
       .setOrigin(0.5, 1)
-      .setPadding(8)
       .setPosition(this.cameras.main.centerX, this.cameras.main.height);
   }