diff --git a/VERSION b/VERSION
index cf8690732fe3ef1414b99886dc496065db8e8712..ef0f38abe163df4bd53e2514ff6bd53e74851eb9 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.18.0
+2.19.0
diff --git a/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png b/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png
index 9c8a007275b711d4a40c2ec5894d588b6ad99295..3dd05fcb306d8054fcccbda04ec22a850022c3e7 100644
Binary files a/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png and b/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png differ
diff --git a/frontend/src/assets/template/make_a_wish_banner/background.png b/frontend/src/assets/template/make_a_wish_banner/background.png
index 5f95bacfb639fa51c190385aadbdf40afd3e77db..63318e77b58f1f61d99a00b165ce28c1a2e11c9a 100644
Binary files a/frontend/src/assets/template/make_a_wish_banner/background.png and b/frontend/src/assets/template/make_a_wish_banner/background.png differ
diff --git a/frontend/src/assets/template/make_a_wish_banner/background_inverted.png b/frontend/src/assets/template/make_a_wish_banner/background_inverted.png
index cfc2af3d4e9169892a32a63e2dc02fe69b8478ff..8dabc3e3ecad9e4c264951d8b32f993265574fbb 100644
Binary files a/frontend/src/assets/template/make_a_wish_banner/background_inverted.png and b/frontend/src/assets/template/make_a_wish_banner/background_inverted.png differ
diff --git a/frontend/src/assets/template/make_a_wish_banner/line.png b/frontend/src/assets/template/make_a_wish_banner/line.png
new file mode 100644
index 0000000000000000000000000000000000000000..bad1684b374622e34daa3eae2d630401bc20c6e0
Binary files /dev/null and b/frontend/src/assets/template/make_a_wish_banner/line.png differ
diff --git a/frontend/src/components/canvas/utils.js b/frontend/src/components/canvas/utils.js
index 97fb8edc76cb81866ed1d461c9c56b8e382377a4..c06b758c9983e0ca56817c85ce232ff4ad868a16 100644
--- a/frontend/src/components/canvas/utils.js
+++ b/frontend/src/components/canvas/utils.js
@@ -17,6 +17,92 @@ const clearObjects = (clearableItems, canvas) => {
   }
 };
 
+const getSingleLineTextBoxWidth = (text, fontSize, fontFamily) => {
+  text = text.replace(/[^\S\r\n]+/g, " ");
+  text = text.replace(/\r\n/g, "\n");
+
+  let positionWithinString = -1;
+
+  const splitWords = text.split(" ");
+  let wordIndexes = {};
+  const spaceText = new fabric.Text(" ", {
+    fontFamily: fontFamily,
+    fontSize: fontSize,
+  });
+
+  // I stole this from another function and this breaks its line width checking system
+  // so that I don't have to modify the way it works because i remember none of this
+  // hacky browser font shit anymore.
+  const maxWidth = 999999999999999;
+  let currentWidth = 0;
+  
+  for (let wordPosition = 0; wordPosition < splitWords.length; wordPosition++) {
+    let currentWord = splitWords[wordPosition];
+    let skipNewLineGeneration = false;
+
+    if (currentWord.includes("\n")) {
+      skipNewLineGeneration = true;
+
+      const breakSplitWord = currentWord.split("\n");
+
+      const firstLineWord = breakSplitWord[0];
+      const secondLineWord = breakSplitWord[1];
+
+      // Word + \n
+      positionWithinString += firstLineWord.length + 1;
+
+      currentWord = secondLineWord;
+    }
+
+    const wordIsLast = wordPosition === splitWords.length - 1;
+
+    positionWithinString += currentWord.length + (!wordIsLast ? 1 : 0);
+
+    const wordText = new fabric.Text(currentWord, {
+      fontFamily: fontFamily,
+      fontSize: fontSize,
+    });
+
+    // This is really ugly, I have no idea why Chromium thinks the text is shorter than it really is.
+    // (Or why Firefox thinks it's longer.)
+    // But, it works.
+    currentWidth += wordText.width * (Boolean(window.chrome) ? 1.183 : 1);
+
+    if (!skipNewLineGeneration && currentWidth > maxWidth) {
+      if (
+        ["a", "i", "o", "u", "s", "se", "v", "z"].includes(
+          splitWords[
+            wordPosition !== 0 ? wordPosition - 1 : wordPosition
+          ].replace("*", ""),
+        )
+      ) {
+        // Previous word is not a, i, o, u, s, ...
+        const lineBreakPosition =
+          positionWithinString -
+          (!wordIsLast ? 1 : 0) -
+          currentWord.length -
+          1 -
+          splitWords[wordPosition !== 0 ? wordPosition - 1 : wordPosition]
+            .length;
+
+        text = setCharAt(text, lineBreakPosition, "\n");
+      } else {
+        text = setCharAt(
+          text,
+          positionWithinString - (!wordIsLast ? 1 : 0) - currentWord.length,
+          "\n",
+        );
+      }
+
+      currentWidth = wordText.width;
+    } else if (!wordIsLast) {
+      currentWidth += spaceText.width;
+    }
+  }
+
+  return currentWidth;
+}
+
 const sortObjects = (canvas) => {
   canvas._objects.sort((a, b) => (a.zIndex > b.zIndex ? 1 : -1));
   canvas.renderAll();
@@ -284,5 +370,6 @@ export {
   sortObjects,
   transformHighlightedText,
   transformTextLineBreaks,
+  getSingleLineTextBoxWidth,
   checkTextBoxHeight,
 };
diff --git a/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js b/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js
index db7fd5781df8bc9ad3c7c49c033bdf23ae13e0e5..f9aa91b6079e3b66a4dbc7ed0fb6727a3cea85b7 100644
--- a/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js
+++ b/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js
@@ -61,26 +61,26 @@ const redraw = async (canvas, options) => {
   canvas.preserveObjectStacking = true;
 
   const textMarginLeft = Math.ceil(canvas.width * 0.1);
-  const textMarginRight = Math.ceil(canvas.width * 0.078);
+  const textMarginRight = Math.ceil(canvas.width * 0.04);
 
-  let mainTextMarginBottom = Math.ceil(canvas.height * 0.3) + Math.ceil(canvas.height * 0.13);
-  const dateTextMarginBottom = Math.ceil(canvas.height * 0.605) + Math.ceil(canvas.height * 0.305);
-  const timeTextBoxMarginBottom = Math.ceil(canvas.height * 0.535) + Math.ceil(canvas.height * 0.312);
-  const locationTextBoxMarginBottom = Math.ceil(canvas.height * 0.27) + Math.ceil(canvas.height * 0.12);
-  const attendeesTextBoxMarginBottom = Math.ceil(canvas.height * 0.09) + Math.ceil(canvas.height * 0.065);
+  let mainTextMarginBottom = Math.ceil(canvas.height * 0.47) + Math.ceil(canvas.height * 0.02);
+  const dateTextMarginBottom = Math.ceil(canvas.height * 0.8) + Math.ceil(canvas.height * 0.069);
+  const timeTextBoxMarginBottom = Math.ceil(canvas.height * 0.715) + Math.ceil(canvas.height * 0.075);
+  const locationTextBoxMarginBottom = Math.ceil(canvas.height * 0.43) + Math.ceil(canvas.height * 0.02);
+  const attendeesTextBoxMarginBottom = Math.ceil(canvas.height * 0.11) + Math.ceil(canvas.height * 0.12);
 
-  const mainTextSize = Math.ceil(canvas.height * 0.175);
+  const mainTextSize = Math.ceil(canvas.height * 0.210);
   const mainTextLineHeight = 1;
 
-  const dateTextSize = Math.ceil(canvas.height * 0.046);
-  const timeTextSize = Math.ceil(canvas.height * 0.04);
-  const attendeesTextSize = Math.ceil(canvas.height * 0.027);
+  const dateTextSize = Math.ceil(canvas.height * 0.062);
+  const timeTextSize = Math.ceil(canvas.height * 0.062);
+  const attendeesTextSize = Math.ceil(canvas.height * 0.035);
   const attendeesTextLineHeight = 1;
 
-  const locationTextSize = Math.ceil(canvas.height * 0.044);
+  const locationTextSize = Math.ceil(canvas.height * 0.055);
   const locationTextLineHeight = 1;
 
-  const contractedByTextSize = Math.ceil(canvas.height * 0.015);
+  const contractedByTextSize = Math.ceil(canvas.height * 0.02);
   const contractedByTextMaxWidth = Math.ceil(canvas.width * 0.9);
   const contractedByTextSidesMargin = Math.ceil(canvas.width * 0.03);
 
diff --git a/frontend/src/views/make_a_wish_banner/canvas.js b/frontend/src/views/make_a_wish_banner/canvas.js
index 620de28ed5d1195bcd51262d4e082281134c5698..883243c9b90d7af4edb14ee609c2f6677ee93104 100644
--- a/frontend/src/views/make_a_wish_banner/canvas.js
+++ b/frontend/src/views/make_a_wish_banner/canvas.js
@@ -4,10 +4,14 @@ import {
   sortObjects,
   transformHighlightedText,
   checkTextBoxHeight,
+  getSingleLineTextBoxWidth,
 } from "../../components/canvas/utils";
 import { PaddedHighlightingTextbox } from "../../components/canvas/textbox";
 import backgroundURL from "../../assets/template/make_a_wish_banner/background.png";
 import backgroundURLInverted from "../../assets/template/make_a_wish_banner/background_inverted.png";
+
+import lineURL from "../../assets/template/make_a_wish_banner/line.png";
+
 import COLORS from "../../colors";
 
 let mainTextBox = null;
@@ -16,6 +20,7 @@ let personNameText = null;
 let personPositionText = null;
 
 let mainImage = null;
+let lineImage = null;
 let backgroundImage = null;
 let previousBackgroundImageColor = null;
 
@@ -26,6 +31,7 @@ let mainImageSource = null;
 const redraw = async (canvas, options) => {
   clearObjects(
     [
+      lineImage,
       mainTextBox,
       personNameText,
       personPositionText,
@@ -34,6 +40,8 @@ const redraw = async (canvas, options) => {
     canvas,
   );
 
+  lineImage = null;
+
   canvas.preserveObjectStacking = true;
 
   const textMarginLeft = Math.ceil(canvas.width * 0.24);
@@ -43,7 +51,7 @@ const redraw = async (canvas, options) => {
   const mainTextBackgroundMarginTop = Math.ceil(canvas.height * 0.14);
   const mainTextSize = Math.ceil(canvas.height * 0.07);
   const mainTextHeightLimit = Math.ceil(mainTextSize * 3.3);
-  const mainTextLineHeight = 1;
+  const mainTextLineHeight = 0.85;
 
   const bottomTextSize = Math.ceil(canvas.height * 0.035);
   const positionTextSize = Math.ceil(canvas.height * 0.025);
@@ -112,7 +120,7 @@ const redraw = async (canvas, options) => {
       personNameText = new fabric.Textbox(options.personName, {
         left: nameTextMarginLeft,
         top: canvas.height - bottomTextSize - nameTextMarginBottom,
-        width: nameTextMaxWidth,
+        width: canvas.width,
         fontFamily: "Bebas Neue",
         fontSize: bottomTextSize,
         styles: styles,
@@ -127,7 +135,7 @@ const redraw = async (canvas, options) => {
         personPositionText = new fabric.Textbox(options.personPosition, {
           left: positionTextSideGap,
           top: canvas.height - bottomTextSize - positionTextMarginBottom,
-          width: positionTextMaxWidth,
+          width: canvas.width,
           fontFamily: "Roboto Condensed",
           fontSize: positionTextSize,
           fill: options.colors.baseText.value,
@@ -160,6 +168,14 @@ const redraw = async (canvas, options) => {
     /* BEGIN Main text render */
 
     const mainTextWidth = canvas.width - textMarginLeft - textMarginRight;
+    let mainTextLeft = textMarginLeft;
+    
+    if (personNameText !== null) {
+      mainTextLeft = Math.max(
+        personNameText.left + getSingleLineTextBoxWidth(options.personName, bottomTextSize, "Roboto Condensed") + 150,
+        mainTextLeft
+      );
+    }
 
     const highlightedData = transformHighlightedText(
       options.mainText,
@@ -173,7 +189,7 @@ const redraw = async (canvas, options) => {
 
     mainTextBox = new PaddedHighlightingTextbox(highlightedData.text, {
       width: canvas.width,
-      left: textMarginLeft,
+      left: mainTextLeft,
       textAlign: "left",
       fontFamily: "Bebas Neue",
       fontSize: mainTextSize,
@@ -185,18 +201,50 @@ const redraw = async (canvas, options) => {
       zIndex: 20,
     });
 
-    checkTextBoxHeight(mainTextBox, 1);
+    checkTextBoxHeight(mainTextBox, 2);
 
     canvas.add(mainTextBox);
 
     const mainTextBoxTop =
-      canvas.height - mainTextBox.height - mainTextMarginBottom;
+      canvas.height - mainTextBox.height - mainTextMarginBottom + (mainTextSize * (mainTextBox._textLines.length - 1) * 0.5 * mainTextLineHeight);
 
     mainTextBox.top = mainTextBoxTop - highlightedData.paddingBottom;
 
     canvas.renderAll();
 
     /* END Main text render */
+
+    /* BEGIN Line render */
+
+    if (lineImage === null || options.colors.background.value != previousBackgroundImageColor.value) {
+      lineImage = new Image();
+
+      await new Promise((resolve) => {
+        lineImage.onload = () => {
+          resolve();
+        };
+
+        if (options.colors.background.value == COLORS.black.value) {
+          lineImage.src = lineURL;
+        } else {
+          lineImage.src = lineURLInverted;
+        }
+      });
+
+      lineImage = new fabric.Image(lineImage, {
+        top: 1690,
+        left: mainTextBox.left - 40,
+        zIndex: 10,
+        selectable: false,
+      });
+      lineImage.scaleToHeight(mainTextLineHeight * mainTextSize * 2);
+
+      console.log(lineImage);
+
+      canvas.add(lineImage);
+    }
+
+    /* END Line render */
   }
 
   /* BEGIN Contracted by render */