diff --git a/VERSION b/VERSION
index b1b25a5ffae43c2f07d222b53240d871e7c1789b..276cbf9e2858c779297bb9f73b34170302949ec4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.2
+2.3.0
diff --git a/frontend/src/components/inputs/SelectInput.vue b/frontend/src/components/inputs/SelectInput.vue
new file mode 100644
index 0000000000000000000000000000000000000000..d7b4352854185e794895986dcecc5687097c5cd5
--- /dev/null
+++ b/frontend/src/components/inputs/SelectInput.vue
@@ -0,0 +1,49 @@
+<script setup>
+import InputHeading from './InputHeading.vue'
+
+import VueSelect from 'vue-select'
+</script>
+
+<script>
+export default {
+    components: { InputHeading, VueSelect },
+    props: ['name', 'important', 'zIndex', 'options', 'modelValue'],
+    emits: ['update:modelValue'],
+    data () {
+        return {
+            currentOption: this.modelValue,
+        }
+    },
+    methods: {
+        setPredefinedColors (value) {
+            this.currentOption = value
+        }
+    },
+    watch: {
+        currentOption (value) {
+            this.$emit('update:modelValue', value);
+        }
+    },
+}
+</script>
+
+<template>
+    <section
+        class="flex flex-col gap-2 bg-gray-100 p-4 drop-shadow-md"
+        :style="{'z-index': zIndex}"
+    >
+        <InputHeading
+            :name="name"
+            :important="important"
+            icon="menu"
+        ></InputHeading>
+
+        <VueSelect
+            :options="options"
+            :clearable="false"
+            :modelValue="modelValue"
+            @update:modelValue="setPredefinedColors"
+            label="name"
+        ></VueSelect>
+    </section>
+</template>
diff --git a/frontend/src/logos.js b/frontend/src/logos.js
index 617d4a47bd6a8ca6feb03dd7bdc6a0f465ec3a13..6963cb4980ad2a473e918ef0656bc34c5102b1fa 100644
--- a/frontend/src/logos.js
+++ b/frontend/src/logos.js
@@ -12,6 +12,39 @@ const LOGOS = {
     }
 }
 
+const LOGO_POSITIONS = {
+    top_left: {
+        "id": "top-left",
+        "name": "Vlevo nahoře"
+    },
+    top_right: {
+        "id": "top-right",
+        "name": "Vpravo nahoře"
+    },
+    bottom_left: {
+        "id": "bottom-left",
+        "name": "Vlevo dole"
+    },
+    bottom_right: {
+        "id": "bottom-right",
+        "name": "Vpravo dole"
+    }
+}
+
+const generateLogoPositions = (identifiers) => {
+    let logoPositionsList = []
+
+    for (const [key, value] of Object.entries(LOGO_POSITIONS)) {
+        if (!identifiers.includes(key)) {
+            continue
+        }
+
+        logoPositionsList.push(value)
+    }
+
+    return logoPositionsList
+}
+
 const generateDefaultLogos = (identifier) => {
     let logosCopy = LOGOS
 
@@ -22,4 +55,4 @@ const generateDefaultLogos = (identifier) => {
     return Object.values(logosCopy)
 }
 
-export { LOGOS, generateDefaultLogos }
+export { LOGOS, generateDefaultLogos, LOGO_POSITIONS, generateLogoPositions }
diff --git a/frontend/src/views/basic_photo_banner/.canvas.js.kate-swp b/frontend/src/views/basic_photo_banner/.canvas.js.kate-swp
new file mode 100644
index 0000000000000000000000000000000000000000..5ad3d57821ae46cb2f2b05a22d852b966247af8f
Binary files /dev/null and b/frontend/src/views/basic_photo_banner/.canvas.js.kate-swp differ
diff --git a/frontend/src/views/basic_photo_banner/BasicPhotoBanner.vue b/frontend/src/views/basic_photo_banner/BasicPhotoBanner.vue
index db708bfd2a94417d5c14e7fd40c972a5271c6880..c3ae42f5f292703f273fbfcb3bd6b281f37a9c0c 100644
--- a/frontend/src/views/basic_photo_banner/BasicPhotoBanner.vue
+++ b/frontend/src/views/basic_photo_banner/BasicPhotoBanner.vue
@@ -5,7 +5,7 @@ import COLORS from '../../colors'
 import PEOPLE from '../../people'
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { generateDefaultLogos } from '../../logos'
+import { generateDefaultLogos, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
 import Canvas from '../../components/canvas/Canvas.vue'
@@ -18,6 +18,7 @@ import LongTextInput from '../../components/inputs/text/LongTextInput.vue'
 import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
 import RangeInput from '../../components/inputs/RangeInput.vue'
 import InputSeparator from '../../components/inputs/InputSeparator.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
@@ -39,6 +40,7 @@ export default {
         LongTextInput,
         ShortTextInput,
         RangeInput,
+        SelectInput,
         InputSeparator,
         MultipleColorPicker
     },
@@ -64,6 +66,13 @@ export default {
             personPosition: null,
             contractedBy: DEFAULT_CONTRACTOR,
             logoImage: null,
+            logoPosition: LOGO_POSITIONS.top_right,
+            logoOptions: generateLogoPositions(
+                [
+                    "top_right",
+                    "top_left",
+                ]
+            ),
             gradientHeightMultiplier: 1,
             colorLabels: {
                 background: 'Pozadí',
@@ -86,6 +95,7 @@ export default {
             const canvasProperties = {
                 mainImage: this.mainImage,
                 mainText: this.mainText,
+                logoPosition: this.logoPosition,
                 personName: this.personName,
                 personPosition: this.personPosition,
                 contractedBy: this.contractedBy,
@@ -105,6 +115,7 @@ export default {
             vm => [
                 vm.mainImage,
                 vm.mainText,
+                vm.logoPosition,
                 vm.personName,
                 vm.personPosition,
                 vm.contractedBy,
@@ -200,6 +211,13 @@ export default {
                     :predefinedImages="predefinedLogoImages"
                     :mustSelectPredefinedImage="true"
                     :disableImageInput="true"
+                    zIndex="7"
+                />
+
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
                     zIndex="6"
                 />
 
diff --git a/frontend/src/views/basic_photo_banner/canvas.js b/frontend/src/views/basic_photo_banner/canvas.js
index 33233f27fd0a809b4eedbe468e7e0907ab200521..623db2193f1a333c57cfc0b524f275a5d5b36c31 100644
--- a/frontend/src/views/basic_photo_banner/canvas.js
+++ b/frontend/src/views/basic_photo_banner/canvas.js
@@ -17,6 +17,7 @@ let contractedByTextbox = null
 let arrow = null
 
 let mainImageSource = null
+let previousLogoPosition = null
 
 const redraw = async (canvas, options) => {
     clearObjects(
@@ -295,30 +296,43 @@ const redraw = async (canvas, options) => {
 
     // A logo is provided, and it either hasn't been rendered yet or is a new one.
     const createNewLogo = (
-        options.logoImage !== null
-        && (
-            logoImage === null
-            || (
-                options.logoImage !== null
-                && options.logoImage !== logoImage._element
+        (
+            options.logoImage !== null
+            && (
+                logoImage === null
+                || (
+                    options.logoImage !== null
+                    && options.logoImage !== logoImage._element
+                )
             )
-        )
+        ) || previousLogoPosition != options.logoPosition.id
     )
 
+    previousLogoPosition = options.logoPosition.id
+
     if (createNewLogo) {
         canvas.remove(logoImage)
 
         logoImage = new fabric.Image(options.logoImage, {selectable: false})
         logoImage.scaleToWidth(logoWidth)
-        logoImage.set({
-            left: (
-                canvas.width
-                - logoWidth
-                - logoSideMargin
-            ),
-            top: logoSideMargin,
-            zIndex: 11,
-        })
+
+        if (options.logoPosition.id == "top-right") {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "top-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        }
 
         canvas.add(logoImage)
     }
diff --git a/frontend/src/views/facebook_survey/.canvas.js.kate-swp b/frontend/src/views/facebook_survey/.canvas.js.kate-swp
new file mode 100644
index 0000000000000000000000000000000000000000..e34d81d5421f5e53e4c99157e3307eb506baf1e6
Binary files /dev/null and b/frontend/src/views/facebook_survey/.canvas.js.kate-swp differ
diff --git a/frontend/src/views/facebook_survey/FacebookSurvey.vue b/frontend/src/views/facebook_survey/FacebookSurvey.vue
index 9b8b9a6f6def00d0b76543517ca1bfe993d2bb6b..d9042fce8024d9defe634c15fc1e2d29925b4906 100644
--- a/frontend/src/views/facebook_survey/FacebookSurvey.vue
+++ b/frontend/src/views/facebook_survey/FacebookSurvey.vue
@@ -4,7 +4,7 @@ import { watch, ref } from 'vue'
 import COLORS from '../../colors'
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { generateDefaultLogos } from '../../logos'
+import { generateDefaultLogos, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
 import Canvas from '../../components/canvas/Canvas.vue'
@@ -18,6 +18,7 @@ import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
 import EmojiInput from '../../components/inputs/EmojiInput.vue'
 import RangeInput from '../../components/inputs/RangeInput.vue'
 import InputSeparator from '../../components/inputs/InputSeparator.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
@@ -60,6 +61,13 @@ export default {
             mainImage: null,
             mainText: null,
             logoImage: null,
+            logoPosition: LOGO_POSITIONS.top_right,
+            logoOptions: generateLogoPositions(
+                [
+                    "top_right",
+                    "top_left",
+                ]
+            ),
             firstEmojiImage: null,
             firstEmojiText: null,
             secondEmojiImage: null,
@@ -89,6 +97,7 @@ export default {
                 mainText: this.mainText,
                 contractedBy: this.contractedBy,
                 logoImage: this.logoImage,
+                logoPosition: this.logoPosition,
                 colors: this.colors,
                 firstEmojiImage: this.firstEmojiImage,
                 secondEmojiImage: this.secondEmojiImage,
@@ -110,6 +119,7 @@ export default {
                 vm.mainText,
                 vm.contractedBy,
                 vm.logoImage,
+                vm.logoPosition,
                 vm.colors,
                 vm.firstEmojiImage,
                 vm.secondEmojiImage,
@@ -228,6 +238,13 @@ export default {
                     :disableImageInput="true"
                     zIndex="4"
                 />
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
+                    zIndex="3"
+                />
+
                 <MultipleColorPicker
                     name="Barvy"
                     v-model="colors"
@@ -235,7 +252,7 @@ export default {
                     :colorLabels="colorLabels"
                     :predefinedColors="predefinedColors"
                     :defaultPredefinedColors="predefinedColors.base"
-                    zIndex="3"
+                    zIndex="2"
                 ></MultipleColorPicker>
 
                 <ShortTextInput
@@ -243,7 +260,7 @@ export default {
                     v-model="contractedBy"
                     :defaultValue="DEFAULT_CONTRACTOR"
                     :important="false"
-                    zIndex="4"
+                    zIndex="1"
                 />
             </template>
         </MainContainer>
diff --git a/frontend/src/views/facebook_survey/canvas.js b/frontend/src/views/facebook_survey/canvas.js
index ee28452932008123f91fff4151b2221cdfd946ab..800428b1f259c6801a00127b16ac47d95a89768a 100644
--- a/frontend/src/views/facebook_survey/canvas.js
+++ b/frontend/src/views/facebook_survey/canvas.js
@@ -20,6 +20,7 @@ let firstEmojiText = null
 let secondEmojiText = null
 
 let mainImageSource = null
+let previousLogoPosition = null
 
 const redraw = async (canvas, options) => {
     clearObjects(
@@ -312,30 +313,43 @@ const redraw = async (canvas, options) => {
 
     // A logo is provided, and it either hasn't been rendered yet or is a new one.
     const createNewLogo = (
-        options.logoImage !== null
-        && (
-            logoImage === null
-            || (
-                options.logoImage !== null
-                && options.logoImage !== logoImage._element
+        (
+            options.logoImage !== null
+            && (
+                logoImage === null
+                || (
+                    options.logoImage !== null
+                    && options.logoImage !== logoImage._element
+                )
             )
-        )
+        ) || previousLogoPosition != options.logoPosition.id
     )
 
+    previousLogoPosition = options.logoPosition.id
+
     if (createNewLogo) {
         canvas.remove(logoImage)
 
         logoImage = new fabric.Image(options.logoImage, {selectable: false})
         logoImage.scaleToWidth(logoWidth)
-        logoImage.set({
-            left: (
-                canvas.width
-                - logoWidth
-                - logoSideMargin
-            ),
-            top: logoSideMargin,
-            zIndex: 11
-        })
+
+        if (options.logoPosition.id == "top-right") {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "top-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        }
 
         canvas.add(logoImage)
     }
diff --git a/frontend/src/views/newspaper_quote_bottom/.canvas.js.kate-swp b/frontend/src/views/newspaper_quote_bottom/.canvas.js.kate-swp
new file mode 100644
index 0000000000000000000000000000000000000000..0a788be2abdadf04c2f0a364b41d7de88daf1daf
Binary files /dev/null and b/frontend/src/views/newspaper_quote_bottom/.canvas.js.kate-swp differ
diff --git a/frontend/src/views/newspaper_quote_bottom/NewspaperQuoteBottom.vue b/frontend/src/views/newspaper_quote_bottom/NewspaperQuoteBottom.vue
index faf64a0d65be4be4343efd4880ef7a045f1dbf8b..10f7fbd18149365204f7fcf75ea63524e388a2b3 100644
--- a/frontend/src/views/newspaper_quote_bottom/NewspaperQuoteBottom.vue
+++ b/frontend/src/views/newspaper_quote_bottom/NewspaperQuoteBottom.vue
@@ -5,7 +5,7 @@ import COLORS from '../../colors'
 import PEOPLE from '../../people'
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { generateDefaultLogos } from '../../logos'
+import { generateDefaultLogos, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { SOURCE_IMAGES } from '../utils/newspaper_quotes'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
@@ -16,8 +16,9 @@ import Navbar from '../../components/Navbar.vue'
 import MainContainer from '../../components/MainContainer.vue'
 import ImageInput from '../../components/inputs/ImageInput.vue'
 import LongTextInput from '../../components/inputs/text/LongTextInput.vue'
-import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue';
+import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
 import InputSeparator from '../../components/inputs/InputSeparator.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
@@ -74,6 +75,13 @@ export default {
             personPosition: null,
             contractedBy: DEFAULT_CONTRACTOR,
             logoImage: null,
+            logoPosition: LOGO_POSITIONS.top_right,
+            logoOptions: generateLogoPositions(
+                [
+                    "top_right",
+                    "top_left",
+                ]
+            ),
             colorLabels: {
                 background: 'Pozadí',
                 highlight: 'Zvýraznění',
@@ -101,6 +109,7 @@ export default {
                 personPosition: this.personPosition,
                 contractedBy: this.contractedBy,
                 logoImage: this.logoImage,
+                logoPosition: this.logoPosition,
                 colors: this.colors
             }
 
@@ -120,6 +129,7 @@ export default {
                 vm.personPosition,
                 vm.contractedBy,
                 vm.logoImage,
+                vm.logoPosition,
                 vm.colors
             ],
             async (value) => {
@@ -246,6 +256,13 @@ export default {
                     :disableImageInput="true"
                     zIndex="5"
                 />
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
+                    zIndex="4"
+                />
+
                 <MultipleColorPicker
                     name="Barvy"
                     v-model="colors"
@@ -253,7 +270,7 @@ export default {
                     :colorLabels="colorLabels"
                     :predefinedColors="predefinedColors"
                     :defaultPredefinedColors="predefinedColors.base"
-                    zIndex="4"
+                    zIndex="3"
                 ></MultipleColorPicker>
 
                 <ShortTextInput
@@ -261,7 +278,7 @@ export default {
                     v-model="contractedBy"
                     :defaultValue="DEFAULT_CONTRACTOR"
                     :important="false"
-                    zIndex="4"
+                    zIndex="2"
                 />
             </template>
         </MainContainer>
diff --git a/frontend/src/views/newspaper_quote_bottom/canvas.js b/frontend/src/views/newspaper_quote_bottom/canvas.js
index 018e7b753b561e52123d5f8ee746a583f71d3fde..5ca754d40a18ee0f1ffcee2efecf78143c6f85d0 100644
--- a/frontend/src/views/newspaper_quote_bottom/canvas.js
+++ b/frontend/src/views/newspaper_quote_bottom/canvas.js
@@ -28,6 +28,7 @@ let tear = null
 let tearFill = null
 
 let mainImageSource = null
+let previousLogoPosition = null
 
 const redraw = async (canvas, options) => {
     clearObjects(
@@ -486,30 +487,43 @@ const redraw = async (canvas, options) => {
 
     // A logo is provided, and it either hasn't been rendered yet or is a new one.
     const createNewLogo = (
-        options.logoImage !== null
-        && (
-            logoImage === null
-            || (
-                options.logoImage !== null
-                && options.logoImage !== logoImage._element
+        (
+            options.logoImage !== null
+            && (
+                logoImage === null
+                || (
+                    options.logoImage !== null
+                    && options.logoImage !== logoImage._element
+                )
             )
-        )
+        ) || previousLogoPosition != options.logoPosition.id
     )
 
+    previousLogoPosition = options.logoPosition.id
+
     if (createNewLogo) {
         canvas.remove(logoImage)
 
         logoImage = new fabric.Image(options.logoImage, {selectable: false})
         logoImage.scaleToWidth(logoWidth)
-        logoImage.set({
-            left: (
-                canvas.width
-                - logoWidth
-                - logoSideMargin
-            ),
-            top: logoSideMargin,
-            zIndex: 11,
-        })
+
+         if (options.logoPosition.id == "top-right") {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "top-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        }
 
         canvas.add(logoImage)
     }
diff --git a/frontend/src/views/newspaper_quote_middle/.canvas.js.kate-swp b/frontend/src/views/newspaper_quote_middle/.canvas.js.kate-swp
new file mode 100644
index 0000000000000000000000000000000000000000..898e4aaee82f3bfe6277de28711572a8cbd62657
Binary files /dev/null and b/frontend/src/views/newspaper_quote_middle/.canvas.js.kate-swp differ
diff --git a/frontend/src/views/newspaper_quote_middle/NewspaperQuoteMiddle.vue b/frontend/src/views/newspaper_quote_middle/NewspaperQuoteMiddle.vue
index f2b35c2031dba8a8ee87b669edcce66a4f269639..6cc011f07643a47fec1c66a90bf745c9d33be7c4 100644
--- a/frontend/src/views/newspaper_quote_middle/NewspaperQuoteMiddle.vue
+++ b/frontend/src/views/newspaper_quote_middle/NewspaperQuoteMiddle.vue
@@ -5,7 +5,7 @@ import COLORS from '../../colors'
 import PEOPLE from '../../people'
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { generateDefaultLogos } from '../../logos'
+import { generateDefaultLogos, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { SOURCE_IMAGES } from '../utils/newspaper_quotes'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
@@ -18,6 +18,7 @@ import ImageInput from '../../components/inputs/ImageInput.vue'
 import LongTextInput from '../../components/inputs/text/LongTextInput.vue'
 import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
 import InputSeparator from '../../components/inputs/InputSeparator.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
@@ -78,6 +79,14 @@ export default {
             personPosition: null,
             contractedBy: DEFAULT_CONTRACTOR,
             logoImage: null,
+            logoPosition: LOGO_POSITIONS.top_right,
+            logoOptions: generateLogoPositions(
+                [
+                    "top_right",
+                    "top_left",
+                    "bottom_left",
+                ]
+            ),
             colorLabels: {
                 background: 'Pozadí',
                 foreground: 'Popředí',
@@ -106,6 +115,7 @@ export default {
                 personPosition: this.personPosition,
                 contractedBy: this.contractedBy,
                 logoImage: this.logoImage,
+                logoPosition: this.logoPosition,
                 colors: this.colors
             }
 
@@ -124,6 +134,7 @@ export default {
                 vm.personPosition,
                 vm.contractedBy,
                 vm.logoImage,
+                vm.logoPosition,
                 vm.colors
             ],
             async (value) => {
@@ -217,6 +228,13 @@ export default {
                     :disableImageInput="true"
                     zIndex="6"
                 />
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
+                    zIndex="5"
+                />
+
                 <MultipleColorPicker
                     name="Barvy"
                     v-model="colors"
@@ -224,7 +242,7 @@ export default {
                     :colorLabels="colorLabels"
                     :predefinedColors="predefinedColors"
                     :defaultPredefinedColors="predefinedColors.base"
-                    zIndex="5"
+                    zIndex="4"
                 ></MultipleColorPicker>
 
                 <ShortTextInput
@@ -232,7 +250,7 @@ export default {
                     v-model="contractedBy"
                     :defaultValue="DEFAULT_CONTRACTOR"
                     :important="false"
-                    zIndex="4"
+                    zIndex="3"
                 />
             </template>
         </MainContainer>
diff --git a/frontend/src/views/newspaper_quote_middle/canvas.js b/frontend/src/views/newspaper_quote_middle/canvas.js
index df78013523aa90ae3eaae8bff767a46bf48b6cd4..cc6c407b58753bf4b1735b9eaab869054b5d9828 100644
--- a/frontend/src/views/newspaper_quote_middle/canvas.js
+++ b/frontend/src/views/newspaper_quote_middle/canvas.js
@@ -31,6 +31,7 @@ let topTearFill = null
 let bottomTearFill = null
 
 let background = null
+let previousLogoPosition = null
 
 const redraw = async (canvas, options) => {
     clearObjects(
@@ -493,30 +494,53 @@ const redraw = async (canvas, options) => {
 
     // A logo is provided, and it either hasn't been rendered yet or is a new one.
     const createNewLogo = (
-        options.logoImage !== null
-        && (
-            logoImage === null
-            || (
-                options.logoImage !== null
-                && options.logoImage !== logoImage._element
+        (
+            options.logoImage !== null
+            && (
+                logoImage === null
+                || (
+                    options.logoImage !== null
+                    && options.logoImage !== logoImage._element
+                )
             )
-        )
+        ) || previousLogoPosition != options.logoPosition.id
     )
 
+    previousLogoPosition = options.logoPosition.id
+
     if (createNewLogo) {
         canvas.remove(logoImage)
 
         logoImage = new fabric.Image(options.logoImage, {selectable: false})
         logoImage.scaleToWidth(logoWidth)
-        logoImage.set({
-            left: (
-                canvas.width
-                - logoWidth
-                - logoSideMargin
-            ),
-            top: logoSideMargin,
-            zIndex: 11,
-        })
+
+        if (options.logoPosition.id == "top-right") {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "top-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "bottom-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: (
+                    canvas.height
+                    - logoSideMargin
+                    - logoImage.getScaledHeight()
+                ),
+                zIndex: 11,
+            })
+        }
 
         canvas.add(logoImage)
     }
diff --git a/frontend/src/views/text_banner/.canvas.js.kate-swp b/frontend/src/views/text_banner/.canvas.js.kate-swp
new file mode 100644
index 0000000000000000000000000000000000000000..6b32485d05a63cf860a44e2d1a4c8c5376cee0c9
Binary files /dev/null and b/frontend/src/views/text_banner/.canvas.js.kate-swp differ
diff --git a/frontend/src/views/text_banner/TextBanner.vue b/frontend/src/views/text_banner/TextBanner.vue
index 438b43ba10590ed0e3f294c347e22f09f440a4c8..1a4bad2f250367ec879e826a7663dfdec654fcc1 100644
--- a/frontend/src/views/text_banner/TextBanner.vue
+++ b/frontend/src/views/text_banner/TextBanner.vue
@@ -4,7 +4,7 @@ import { watch, ref } from 'vue';
 import COLORS from '../../colors';
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { generateDefaultLogos } from '../../logos'
+import { LOGOS, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
 import Canvas from '../../components/canvas/Canvas.vue'
@@ -15,6 +15,7 @@ import MainContainer from '../../components/MainContainer.vue'
 import ImageInput from '../../components/inputs/ImageInput.vue'
 import LongTextInput from '../../components/inputs/text/LongTextInput.vue'
 import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
@@ -57,6 +58,15 @@ export default {
             mainText: null,
             contractedBy: DEFAULT_CONTRACTOR,
             logoImage: null,
+            logoPosition: LOGO_POSITIONS.top_right,
+            logoOptions: generateLogoPositions(
+                [
+                    "top_right",
+                    "top_left",
+                    "bottom_left",
+                    "bottom_right",
+                ]
+            ),
             colorLabels: {
                 background: 'Pozadí',
                 highlight: 'Zvýraznění',
@@ -66,7 +76,13 @@ export default {
             },
             predefinedColors: predefinedColors,
             colors: predefinedColors.base.colors,
-            predefinedLogoImages: generateDefaultLogos('defaultLight'),
+            predefinedLogoImages: [
+                {
+                    name: LOGOS.defaultLight.name,
+                    src: LOGOS.defaultLight.src,
+                    defaultSelected: true,
+                },
+            ],
             autoRedraw: false
         }
     },
@@ -79,6 +95,7 @@ export default {
                 mainText: this.mainText,
                 contractedBy: this.contractedBy,
                 logoImage: this.logoImage,
+                logoPosition: this.logoPosition,
                 colors: this.colors
             }
 
@@ -94,6 +111,7 @@ export default {
                 vm.mainText,
                 vm.contractedBy,
                 vm.logoImage,
+                vm.logoPosition,
                 vm.colors
             ],
             async (value) => {
@@ -153,6 +171,7 @@ export default {
                     :highlightable="true"
                     zIndex="10"
                 />
+
                 <ImageInput
                     name="Obrázek loga"
                     v-model="logoImage"
@@ -162,6 +181,13 @@ export default {
                     :disableImageInput="true"
                     zIndex="9"
                 />
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
+                    zIndex="8"
+                />
+
                 <MultipleColorPicker
                     name="Barvy"
                     v-model="colors"
@@ -169,7 +195,7 @@ export default {
                     :colorLabels="colorLabels"
                     :predefinedColors="predefinedColors"
                     :defaultPredefinedColors="predefinedColors.base"
-                    zIndex="8"
+                    zIndex="7"
                 ></MultipleColorPicker>
 
                 <ShortTextInput
diff --git a/frontend/src/views/text_banner/canvas.js b/frontend/src/views/text_banner/canvas.js
index 8bc6694e0606ef0527fb516eb9b27b02dfc8c67c..f4edcb4a5aec9811d918b41e243cc62547116aa9 100644
--- a/frontend/src/views/text_banner/canvas.js
+++ b/frontend/src/views/text_banner/canvas.js
@@ -10,6 +10,7 @@ let arrow = null
 let contractedByTextbox = null
 
 let logoImage = null
+let previousLogoPosition = null
 
 const redraw = async (canvas, options) => {
     clearObjects(
@@ -67,30 +68,67 @@ const redraw = async (canvas, options) => {
 
     // A logo is provided, and it either hasn't been rendered yet or is a new one.
     const createNewLogo = (
-        options.logoImage !== null
-        && (
-            logoImage === null
-            || (
-                options.logoImage !== null
-                && options.logoImage !== logoImage._element
+        (
+            options.logoImage !== null
+            && (
+                logoImage === null
+                || (
+                    options.logoImage !== null
+                    && options.logoImage !== logoImage._element
+                )
             )
-        )
+        ) || previousLogoPosition != options.logoPosition.id
     )
 
+    previousLogoPosition = options.logoPosition.id
+
     if (createNewLogo) {
         canvas.remove(logoImage)
 
         logoImage = new fabric.Image(options.logoImage, {selectable: false})
         logoImage.scaleToWidth(logoWidth)
-        logoImage.set({
-            left: (
-                canvas.width
-                - logoWidth
-                - logoSideMargin
-            ),
-            top: logoTopMargin,
-            zIndex: 11,
-        })
+
+        if (options.logoPosition.id == "top-right") {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: logoTopMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "top-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: logoTopMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "bottom-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: (
+                    canvas.height
+                    - logoTopMargin
+                    - logoImage.getScaledHeight()
+                ),
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "bottom-right") {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: (
+                    canvas.height
+                    - logoTopMargin
+                    - logoImage.getScaledHeight()
+                ),
+                zIndex: 11,
+            })
+        }
 
         canvas.add(logoImage)
     }
diff --git a/frontend/src/views/twitter_banner/.canvas.js.kate-swp b/frontend/src/views/twitter_banner/.canvas.js.kate-swp
new file mode 100644
index 0000000000000000000000000000000000000000..b4b8c03155e83df15a01fcb092ca20ed5809ad4b
Binary files /dev/null and b/frontend/src/views/twitter_banner/.canvas.js.kate-swp differ
diff --git a/frontend/src/views/twitter_banner/TwitterBanner.vue b/frontend/src/views/twitter_banner/TwitterBanner.vue
index 91a7f7329112d967d17d1422a756a1919081ceb7..45ed10d517ea1df91665557827e020177b560035 100644
--- a/frontend/src/views/twitter_banner/TwitterBanner.vue
+++ b/frontend/src/views/twitter_banner/TwitterBanner.vue
@@ -4,7 +4,7 @@ import { watch, ref } from 'vue'
 import COLORS from '../../colors'
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { generateDefaultLogos } from '../../logos'
+import { generateDefaultLogos, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
 import defaultDarkLogoImage from '../../assets/logos/default-dark.png'
@@ -17,6 +17,7 @@ import MainContainer from '../../components/MainContainer.vue'
 import LongTextInput from '../../components/inputs/text/LongTextInput.vue'
 import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
 import PersonInput from './PersonInput.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
 
@@ -83,6 +84,13 @@ export default {
             personTwitter: null,
             contractedBy: DEFAULT_CONTRACTOR,
             logoImageSource: defaultDarkLogoImage,
+            logoPosition: LOGO_POSITIONS.bottom_left,
+            logoOptions: generateLogoPositions(
+                [
+                    "bottom_left",
+                    "top_left",
+                ]
+            ),
             twitterLogoImageSource: twitterLogoImage,
             colors: {
                 background: COLORS.white,
@@ -102,6 +110,7 @@ export default {
             const canvasProperties = {
                 colors: this.colors,
                 logoImageSource: this.logoImageSource,
+                logoPosition: this.logoPosition,
                 twitterLogoImageSource: this.twitterLogoImageSource,
                 mainImage: this.mainImage,
                 mainText: this.mainText,
@@ -121,6 +130,7 @@ export default {
             vm => [
                 vm.colors,
                 vm.logoImageSource,
+                vm.logoPosition,
                 vm.twitterLogoImageSource,
                 vm.mainImage,
                 vm.mainText,
@@ -179,7 +189,7 @@ export default {
                     v-model="autoRedraw"
                 />
                 <PersonInput
-                    name="Člověk"
+                    name="Osoba"
                     v-model:mainImage="mainImage"
                     v-model:personName="personName"
                     v-model:personTwitter="personTwitter"
@@ -195,6 +205,13 @@ export default {
                     zIndex="9"
                 />
 
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
+                    zIndex="8"
+                />
+
                 <ShortTextInput
                     name="Zadavatel a zpracovatel"
                     v-model="contractedBy"
diff --git a/frontend/src/views/twitter_banner/canvas.js b/frontend/src/views/twitter_banner/canvas.js
index 65e4b26606cda5377273341365b8555ed3888174..aaed6513d0d4aad36b5912a5f26de133c95523f8 100644
--- a/frontend/src/views/twitter_banner/canvas.js
+++ b/frontend/src/views/twitter_banner/canvas.js
@@ -13,6 +13,7 @@ let contractedByTextbox = null
 let mainImage = null
 let logoImage = null
 let twitterLogoImage = null
+let previousLogoPosition = null
 
 const redraw = async (canvas, options) => {
     clearObjects(
@@ -223,7 +224,11 @@ const redraw = async (canvas, options) => {
 
     /* BEGIN Logo render */
 
-    if (logoImage === null) {
+    if (logoImage === null || previousLogoPosition != options.logoPosition.id) {
+        if (logoImage !== null) {
+            canvas.remove(logoImage)
+        }
+
         const logoImageElement = new Image();
 
         await new Promise(
@@ -238,19 +243,30 @@ const redraw = async (canvas, options) => {
 
         logoImage = new fabric.Image(logoImageElement, {selectable: false})
         logoImage.scaleToWidth(logoWidth)
-        logoImage.set({
-            left: logoSideMargin,
-            top: (
-                canvas.height
-                - logoSideMargin
-                - logoImage.getScaledHeight()
-            ),
-            zIndex: 11,
-        })
+
+        if (options.logoPosition.id == "top-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: logoSideMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "bottom-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: (
+                    canvas.height
+                    - logoSideMargin
+                    - logoImage.getScaledHeight()
+                ),
+                zIndex: 11,
+            })
+        }
 
         canvas.add(logoImage)
     }
 
+    previousLogoPosition = options.logoPosition.id
+
     /* END Logo render */
 
 
diff --git a/frontend/src/views/urgent_basic_photo_banner/UrgentBasicPhotoBanner.vue b/frontend/src/views/urgent_basic_photo_banner/UrgentBasicPhotoBanner.vue
index aafe79f631f3e4a752544294ea9f9865599c7001..73efe42b931a691d4c49006a58cabc2682149324 100644
--- a/frontend/src/views/urgent_basic_photo_banner/UrgentBasicPhotoBanner.vue
+++ b/frontend/src/views/urgent_basic_photo_banner/UrgentBasicPhotoBanner.vue
@@ -5,7 +5,7 @@ import COLORS from '../../colors'
 import PEOPLE from '../../people'
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { generateDefaultLogos } from '../../logos'
+import { generateDefaultLogos, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
 import Canvas from '../../components/canvas/Canvas.vue'
@@ -18,6 +18,7 @@ import LongTextInput from '../../components/inputs/text/LongTextInput.vue'
 import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
 import RangeInput from '../../components/inputs/RangeInput.vue'
 import InputSeparator from '../../components/inputs/InputSeparator.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
@@ -64,6 +65,13 @@ export default {
             personPosition: null,
             contractedBy: DEFAULT_CONTRACTOR,
             logoImage: null,
+            logoPosition: LOGO_POSITIONS.top_right,
+            logoOptions: generateLogoPositions(
+                [
+                    "top_right",
+                    "top_left",
+                ]
+            ),
             gradientHeightMultiplier: 1,
             colorLabels: {
                 background: 'Pozadí',
@@ -90,6 +98,7 @@ export default {
                 personPosition: this.personPosition,
                 contractedBy: this.contractedBy,
                 logoImage: this.logoImage,
+                logoPosition: this.logoPosition,
                 gradientHeightMultiplier: this.gradientHeightMultiplier,
                 colors: this.colors
             }
@@ -109,6 +118,7 @@ export default {
                 vm.personPosition,
                 vm.contractedBy,
                 vm.logoImage,
+                vm.logoPosition,
                 vm.gradientHeightMultiplier,
                 vm.colors
             ],
@@ -200,6 +210,13 @@ export default {
                     :predefinedImages="predefinedLogoImages"
                     :mustSelectPredefinedImage="true"
                     :disableImageInput="true"
+                    zIndex="7"
+                />
+
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
                     zIndex="6"
                 />
 
diff --git a/frontend/src/views/urgent_text_banner/UrgentTextBanner.vue b/frontend/src/views/urgent_text_banner/UrgentTextBanner.vue
index 8aa62fd70954a5b65e246ccd8eed282d363838d2..137bc55debe712c8e98e0a73302c0dc12eecaff1 100644
--- a/frontend/src/views/urgent_text_banner/UrgentTextBanner.vue
+++ b/frontend/src/views/urgent_text_banner/UrgentTextBanner.vue
@@ -4,7 +4,7 @@ import { watch, ref } from 'vue';
 import COLORS from '../../colors';
 import TEMPLATES from '../../templates'
 import DEFAULT_CONTRACTOR from '../../contractors'
-import { LOGOS } from '../../logos'
+import { LOGOS, LOGO_POSITIONS, generateLogoPositions } from '../../logos'
 import { loadFonts, loadCanvasStorage, setCanvasStorage, updateAutoRedrawStorage } from '../../utils'
 
 import Canvas from '../../components/canvas/Canvas.vue'
@@ -16,6 +16,7 @@ import ImageInput from '../../components/inputs/ImageInput.vue'
 import LongTextInput from '../../components/inputs/text/LongTextInput.vue'
 import ShortTextInput from '../../components/inputs/text/ShortTextInput.vue'
 import MultipleColorPicker from '../../components/inputs/colors/MultipleColorPicker.vue'
+import SelectInput from '../../components/inputs/SelectInput.vue'
 import ReloadButton from '../../components/reload/ReloadButton.vue'
 import AutoReloadCheckbox from '../../components/reload/AutoReloadCheckbox.vue'
 </script>
@@ -54,6 +55,15 @@ export default {
             mainText: null,
             contractedBy: DEFAULT_CONTRACTOR,
             logoImage: null,
+            logoPosition: LOGO_POSITIONS.top_right,
+            logoOptions: generateLogoPositions(
+                [
+                    "top_right",
+                    "top_left",
+                    "bottom_left",
+                    "bottom_right",
+                ]
+            ),
             colorLabels: {
                 background: 'Pozadí',
                 cross: 'Kříž',
@@ -80,6 +90,7 @@ export default {
                 mainText: this.mainText,
                 contractedBy: this.contractedBy,
                 logoImage: this.logoImage,
+                logoPosition: this.logoPosition,
                 colors: this.colors
             }
 
@@ -95,6 +106,7 @@ export default {
                 vm.mainText,
                 vm.contractedBy,
                 vm.logoImage,
+                vm.logoPosition,
                 vm.colors
             ],
             async (value) => {
@@ -154,6 +166,7 @@ export default {
                     :highlightable="false"
                     zIndex="10"
                 />
+
                 <ImageInput
                     name="Obrázek loga"
                     v-model="logoImage"
@@ -163,6 +176,13 @@ export default {
                     :disableImageInput="true"
                     zIndex="9"
                 />
+                <SelectInput
+                    name="Pozice loga"
+                    :options="logoOptions"
+                    v-model="logoPosition"
+                    zIndex="8"
+                />
+
                 <MultipleColorPicker
                     name="Barvy"
                     v-model="colors"
@@ -170,7 +190,7 @@ export default {
                     :colorLabels="colorLabels"
                     :predefinedColors="predefinedColors"
                     :defaultPredefinedColors="predefinedColors.base"
-                    zIndex="8"
+                    zIndex="7"
                 ></MultipleColorPicker>
 
                 <ShortTextInput
diff --git a/frontend/src/views/urgent_text_banner/canvas.js b/frontend/src/views/urgent_text_banner/canvas.js
index ad8b1f5235edd921c223644da90ee3f7af5cb8b0..0fe5a83684277befdd8790d93e0dfa43cc143bab 100644
--- a/frontend/src/views/urgent_text_banner/canvas.js
+++ b/frontend/src/views/urgent_text_banner/canvas.js
@@ -7,6 +7,7 @@ let contractedByTextbox = null
 let textBox = null
 let backgroundImage = null
 let logoImage = null
+let previousLogoPosition = null
 
 const redraw = async (canvas, options) => {
     clearObjects(
@@ -66,30 +67,67 @@ const redraw = async (canvas, options) => {
 
     // A logo is provided, and it either hasn't been rendered yet or is a new one.
     const createNewLogo = (
-        options.logoImage !== null
-        && (
-            logoImage === null
-            || (
-                options.logoImage !== null
-                && options.logoImage !== logoImage._element
+        (
+            options.logoImage !== null
+            && (
+                logoImage === null
+                || (
+                    options.logoImage !== null
+                    && options.logoImage !== logoImage._element
+                )
             )
-        )
+        ) || previousLogoPosition != options.logoPosition.id
     )
 
+    previousLogoPosition = options.logoPosition.id
+
     if (createNewLogo) {
         canvas.remove(logoImage)
 
         logoImage = new fabric.Image(options.logoImage, {selectable: false})
         logoImage.scaleToWidth(logoWidth)
-        logoImage.set({
-            left: (
-                canvas.width
-                - logoWidth
-                - logoSideMargin
-            ),
-            top: logoTopMargin,
-            zIndex: 11,
-        })
+
+        if (options.logoPosition.id == "top-right") {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: logoTopMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "top-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: logoTopMargin,
+                zIndex: 11,
+            })
+        } else if (options.logoPosition.id == "bottom-left") {
+            logoImage.set({
+                left: logoSideMargin,
+                top: (
+                    canvas.height
+                    - logoTopMargin
+                    - logoImage.getScaledHeight()
+                ),
+                zIndex: 11,
+            })
+        } else {
+            logoImage.set({
+                left: (
+                    canvas.width
+                    - logoWidth
+                    - logoSideMargin
+                ),
+                top: (
+                    canvas.height
+                    - logoTopMargin
+                    - logoImage.getScaledHeight()
+                ),
+                zIndex: 11,
+            })
+        }
 
         canvas.add(logoImage)
     }