diff --git a/VERSION b/VERSION
index dc1e644a1014338ad0ca67b5c0bfbd2402e761ee..9c6d6293b1a8f448def89c2d5bfa63b89a24e0cc 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.0
+1.6.1
diff --git a/generator/static/images/examples/bottom-slogan-quote.png b/generator/static/images/examples/bottom-slogan-quote.png
new file mode 100644
index 0000000000000000000000000000000000000000..fdf4da455454b3f16f17aea73a7566d9c0b32021
Binary files /dev/null and b/generator/static/images/examples/bottom-slogan-quote.png differ
diff --git a/generator/static/js/templates/bottom-slogan-quote.js b/generator/static/js/templates/bottom-slogan-quote.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe82b3f0c62c57791a99cd89c6936ebb84e9a8a9
--- /dev/null
+++ b/generator/static/js/templates/bottom-slogan-quote.js
@@ -0,0 +1,927 @@
+class BottomSloganQuote extends Template {
+	description = "Určeno pro sociální sítě.";
+	
+	changeableAttributes = [
+		"logoImage",
+		"primaryImage",
+		"secondaryImage",
+		"primaryImagePosition",
+		"primaryColorScheme",
+		"primaryText",
+		"nameText"
+	];
+
+	secondaryImage = null;
+
+	primaryColorSchemes = [
+		"black-on-white",
+		"white-on-black"
+	];
+
+	// Colors
+	changeableColors = [
+		"foregroundColor",
+		"backgroundColor",
+		"primaryTextColor",
+		"primaryTextHighlightColor",
+		"nameBackgroundColor",
+		"nameTextColor"
+	];
+
+	// Canvas
+	async redrawCanvas() {
+		if (this.redrawing) {
+			return;
+		}
+		
+		this.redrawing = true;
+		
+		// Foreground rectangle
+		const backgroundRectangleOffsetSides = Math.ceil(this.canvas.width * 0.05);
+		const backgroundRectanglePaddingSides = Math.ceil(this.canvas.width * 0.025);
+		const backgroundRectangleAngle = Math.ceil(this.canvas.height * 0.01);
+		const backgroundRectangleOffsetBottom = Math.ceil(this.canvas.height * 0.17);
+		const backgroundRectanglePaddingTop = Math.ceil(this.canvas.height * 0.005);
+		const backgroundRectanglePaddingTopWithNameOrDiacritics = Math.ceil(this.canvas.height * 0.0225);
+		const backgroundRectanglePaddingBottom = Math.ceil(this.canvas.height * 0.035);
+		
+		// Secondary image
+		const secondaryImagePadding = Math.ceil(this.canvas.width * 0.025);
+		
+		// Primary text
+		let primaryTextFontSize = Math.ceil(this.canvas.height * 0.09);
+		let primaryTextMaxLines = 3;
+		
+		// Primary text highlighting
+		const primaryTextHighlightPaddingSides = Math.ceil(this.canvas.width * 0.01);
+		const primaryTextHighlightPaddingTop = Math.ceil(this.canvas.height * -0.005);
+		const primaryTextHighlightPaddingBottom = Math.ceil(this.canvas.height * 0.01);
+		
+		// Name text
+		let nameTextFontSize = Math.ceil(this.canvas.height * 0.03);
+		const nameTextMaxWidth = Math.ceil(this.canvas.width * 0.35);
+		
+		// Name rectangle
+		const nameRectangleOffsetSide = Math.ceil(this.canvas.width * 0.025);
+		const nameRectangleOffsetTop = Math.ceil(this.canvas.height * 0.03);
+		const nameRectanglePaddingSides = Math.ceil(this.canvas.width * 0.025);
+		const nameRectanglePaddingTop = Math.ceil(this.canvas.height * 0.01);
+		const nameRectanglePaddingBottom = Math.ceil(this.canvas.height * 0.0175);
+		
+		// Logo
+		const logoWidth = Math.ceil(this.canvas.width * 0.18) * this.logoImageZoom;
+		const logoOffsetBottom = Math.ceil(this.canvas.height * 0.07) * ((3 - this.logoImageZoom) / 2);
+		const logoOffsetSide = Math.ceil(this.canvas.width * 0.07) * ((3 - this.logoImageZoom) / 2);
+		
+		// Clear the canvas
+		this.context.clearRect(
+			0, 0,
+			this.canvas.width, this.canvas.height
+		);
+		
+		// Set image
+		if (this.primaryImage !== null) {
+			// https://github.com/DonkeyDushan/piratilol/blob/main/src/js/index.js
+			// Thanks to DonkeyDushan, the guy who made the joke 2021 campaign generator :D
+			
+			const imageScaleX = this.canvas.width / this.primaryImage.width;
+			const imageScaleY = this.canvas.height / this.primaryImage.height;
+			
+			const imageScale = Math.max(imageScaleX, imageScaleY) * this.primaryImageZoom;
+			
+			// https://stackoverflow.com/a/8529655
+			// Thanks to alex!
+			this.context.setTransform(
+				imageScale,
+				0, 0,
+				imageScale,
+				(this.canvas.width - this.primaryImage.width * imageScale) / 2 + this.primaryImageX * this.primaryImageZoom,
+				(this.canvas.height - this.primaryImage.height * imageScale) / 2 + this.primaryImageY * this.primaryImageZoom,
+			);
+			this.context.drawImage(
+				this.primaryImage,
+				0, 0
+			);
+			this.context.setTransform(); // Reset transformation
+		}
+		
+		// Create primary text
+		const primaryTextMaxWidth = (
+			this.canvas.width
+			- backgroundRectangleOffsetSides * 2
+			- backgroundRectanglePaddingSides * 2
+			- (
+				backgroundRectanglePaddingBottom
+				+ primaryTextMaxLines * primaryTextFontSize
+				+ backgroundRectanglePaddingTop
+				+ backgroundRectanglePaddingTopWithNameOrDiacritics
+			)
+		);
+		
+		let primaryTextLines = null;
+		const originalPrimaryTextFontSize = primaryTextFontSize;
+		
+		do {
+			this.context.font = `${this.primaryFontStyle} ${primaryTextFontSize}px ${this.primaryFont}`;
+			
+			primaryTextLines = splitStringIntoLines(
+				this.context,
+				this.primaryText,
+				primaryTextMaxWidth,
+				primaryTextMaxLines,
+				true
+			);
+			
+			if (
+				primaryTextLines.length > primaryTextMaxLines
+				&& (
+					primaryTextLines.length * primaryTextFontSize
+					> primaryTextMaxLines * originalPrimaryTextFontSize
+				)
+			) {
+				primaryTextFontSize -= 2;
+			}
+		} while (
+			primaryTextLines.length > primaryTextMaxLines
+			&& (
+				primaryTextLines.length * primaryTextFontSize
+				> primaryTextMaxLines * originalPrimaryTextFontSize
+			)
+		);
+		
+		const firstPrimaryLine = primaryTextLines[0].toString();
+		
+		let secondaryImageWidthHeight = null;
+		
+		// Create background rectangle
+		if (this.primaryText !== "") {
+			const useAdditionalDiacriticsPadding = (
+				this.nameText !== ""
+				|| (
+					firstPrimaryLine.replace(/[a-zA-Z0-9À-ž]+/g, "").length
+					!== firstPrimaryLine.replace(/[a-zA-Z0-9]+/g, "").length
+				)
+			);
+
+			const backgroundRectangleHeight = (
+				backgroundRectanglePaddingBottom
+				+ primaryTextMaxLines * originalPrimaryTextFontSize
+				+ backgroundRectanglePaddingTop
+				+ (
+					(useAdditionalDiacriticsPadding) ?
+					backgroundRectanglePaddingTopWithNameOrDiacritics : 0
+				)
+			);
+			
+			this.context.fillStyle = this.backgroundColor;
+			
+			secondaryImageWidthHeight = backgroundRectangleHeight;
+			
+			this.context.beginPath();
+			this.context.moveTo(
+				backgroundRectangleOffsetSides + secondaryImageWidthHeight / 2,
+				this.canvas.height - backgroundRectangleOffsetBottom
+			);
+			this.context.lineTo(
+				this.canvas.width - backgroundRectangleOffsetSides,
+				this.canvas.height - backgroundRectangleOffsetBottom - backgroundRectangleAngle
+			);
+			this.context.lineTo(
+				this.canvas.width - backgroundRectangleOffsetSides,
+				this.canvas.height - backgroundRectangleOffsetBottom - backgroundRectangleHeight - backgroundRectangleAngle
+			);
+			this.context.lineTo(
+				backgroundRectangleOffsetSides + secondaryImageWidthHeight / 2,
+				this.canvas.height - backgroundRectangleOffsetBottom - backgroundRectangleHeight
+			);
+			this.context.closePath();
+			
+			this.context.fill();
+			
+			this.context.font = `${this.primaryFontStyle} ${primaryTextFontSize}px ${this.primaryFont}`;
+			
+			let currentPrimaryLineY = (
+				this.canvas.height
+				- backgroundRectangleOffsetBottom
+				- backgroundRectanglePaddingBottom
+				- (
+					backgroundRectangleHeight
+					- primaryTextFontSize * primaryTextLines.length
+				) / 2
+				+ backgroundRectanglePaddingTop
+				+ (
+					(useAdditionalDiacriticsPadding) ?
+					backgroundRectanglePaddingTopWithNameOrDiacritics : primaryTextFontSize * 0.2 // general font weirdness
+				)
+			);
+			this.context.textAlign = "left";
+			
+			const backgroundRGB = hexToRgb(this.backgroundColor);
+			const backgroundLightness = (
+				0.2126 * backgroundRGB.r
+				+ 0.7152 * backgroundRGB.g
+				+ 0.0722 * backgroundRGB.b
+			);
+			
+			this.backgroundLightness = backgroundLightness;
+			
+			const primaryLineX = (
+				backgroundRectangleOffsetSides
+				+ backgroundRectanglePaddingSides
+				+ secondaryImageWidthHeight
+			);
+			
+			const useLightHighlight = (backgroundLightness > 207);
+			let previousWordHighlighted = false;
+			let primaryTextHighlightedColor = null;
+			const primaryRectangleWidth = (
+				this.canvas.width
+				- backgroundRectanglePaddingSides * 2
+				- backgroundRectangleOffsetSides * 2
+			);
+			
+			const lowercasePrimaryTextHighlightColor = this.primaryTextHighlightColor.toLowerCase();
+			const hasColorOverride = (
+				lowercasePrimaryTextHighlightColor === "#209a37" ||
+				lowercasePrimaryTextHighlightColor === "#e63812"
+			);
+		
+			if (hasColorOverride) {
+				if (useLightHighlight) {
+					primaryTextHighlightedColor = this.foregroundColor;
+				} else {
+					primaryTextHighlightedColor = this.primaryTextColor;
+				}
+			} else if (!useLightHighlight) {
+				primaryTextHighlightedColor = this.foregroundColor;
+			} else {
+				primaryTextHighlightedColor = this.primaryTextColor;
+			}
+			
+			this.context.fillStyle = this.primaryTextColor;
+			
+			let linePosition = 0;
+			
+			for (const line of primaryTextLines.reverse()) {
+				linePosition++;
+				previousWordHighlighted = false;
+				let wordPosition = 0;
+				
+				for (let word of line) {
+					const spaceWidth = this.context.measureText(" ").width;
+					
+					const previousWords = line.slice(0, wordPosition).join(" ");
+					const previousWordsWidth = (
+						this.context.measureText(previousWords).width
+						+ (
+							(previousWords.length !== 0) ?
+							spaceWidth : 0
+						)
+					);
+					
+					const currentWordWidth = this.context.measureText(word).width;
+					
+					if (word.isHighlighted) {
+						this.context.fillStyle = this.primaryTextHighlightColor;
+						this.context.beginPath();
+						
+						this.context.moveTo(
+							primaryLineX + previousWordsWidth - (
+								(previousWordHighlighted) ?
+								spaceWidth : primaryTextHighlightPaddingSides
+							),
+							currentPrimaryLineY - primaryTextFontSize - primaryTextHighlightPaddingTop
+						);
+						this.context.lineTo(
+							primaryLineX + previousWordsWidth + currentWordWidth + primaryTextHighlightPaddingSides,
+							(
+								currentPrimaryLineY
+								- primaryTextFontSize
+								- Math.max(currentWordWidth / primaryRectangleWidth)
+								- primaryTextHighlightPaddingTop
+							)
+						);
+						this.context.lineTo(
+							primaryLineX + previousWordsWidth + currentWordWidth + primaryTextHighlightPaddingSides,
+							currentPrimaryLineY + primaryTextHighlightPaddingBottom
+						);
+						this.context.lineTo(
+							primaryLineX + previousWordsWidth - (
+								(previousWordHighlighted) ?
+								spaceWidth : primaryTextHighlightPaddingSides
+							), 
+							currentPrimaryLineY + primaryTextHighlightPaddingBottom + Math.max(
+								currentWordWidth / primaryRectangleWidth
+							)
+						);
+						
+						this.context.fill();
+						
+						this.context.fillStyle = primaryTextHighlightedColor;
+						
+						previousWordHighlighted = true;
+					} else {
+						previousWordHighlighted = false;
+					}
+					
+					this.context.fillText(
+						word + " ",
+						(
+							primaryLineX
+							+ previousWordsWidth
+						),
+						currentPrimaryLineY
+					);
+
+					wordPosition++;
+					
+					this.context.fillStyle = this.primaryTextColor;
+				}
+				
+				currentPrimaryLineY -= primaryTextFontSize;
+			}
+			
+			this.context.textAlign = "left";
+			
+			// Create name text
+			if (this.nameText !== "") {
+				do {
+					this.context.font = `${nameTextFontSize}px 'Roboto Condensed'`;
+					
+					if (
+						this.context.measureText(this.nameText).width
+						> nameTextMaxWidth
+					) {
+						nameTextFontSize -= 2;
+					}
+				} while (this.context.measureText(this.nameText).width > nameTextMaxWidth);
+				
+				this.context.fillStyle = this.nameBackgroundColor;
+				this.context.fillRect(
+					(
+						backgroundRectangleOffsetSides
+						+ nameRectangleOffsetSide
+					), (
+						this.canvas.height
+						- backgroundRectangleHeight
+						- backgroundRectangleOffsetBottom
+						- nameRectanglePaddingBottom
+						- nameRectanglePaddingTop
+						- nameTextFontSize
+						+ nameRectangleOffsetTop
+					),
+					(
+						nameRectanglePaddingSides * 2
+						+ this.context.measureText(this.nameText).width
+					),
+					(
+						nameRectanglePaddingBottom
+						+ nameRectanglePaddingTop
+						+ nameTextFontSize
+					)
+				);
+				
+				this.context.fillStyle = this.nameTextColor;
+				
+				this.context.fillText(
+					this.nameText,
+					(
+						backgroundRectangleOffsetSides
+						+ nameRectangleOffsetSide
+						+ nameRectanglePaddingSides
+					),
+					(
+						this.canvas.height
+						- backgroundRectangleHeight
+						- backgroundRectangleOffsetBottom
+						- nameRectanglePaddingBottom
+						+ nameRectangleOffsetTop
+					)
+				);
+			}
+			
+			//// Create secondary image
+			// Background circle
+			this.context.beginPath();
+			this.context.arc(
+				(
+					backgroundRectangleOffsetSides
+					+ secondaryImageWidthHeight / 2
+				),
+				(
+					this.canvas.height
+					- backgroundRectangleOffsetBottom
+					- secondaryImageWidthHeight / 2
+				),
+				secondaryImageWidthHeight / 2, // Radius
+				0,
+				2 * Math.PI,
+				false
+			);
+			this.context.closePath();
+			
+			this.context.fillStyle = this.foregroundColor;
+			this.context.fill();
+		}
+		
+		const classRef = this;
+		
+		if (this.secondaryImage !== null) {
+			const secondaryImageHelperCanvas = document.createElement("canvas");
+			
+			secondaryImageHelperCanvas.width =
+			secondaryImageHelperCanvas.height =
+			secondaryImageWidthHeight;
+			
+			const secondaryImageHelperContext = secondaryImageHelperCanvas.getContext("2d");
+			
+			secondaryImageHelperContext.drawImage(
+				this.secondaryImage,
+				secondaryImagePadding, secondaryImagePadding,
+				secondaryImageHelperCanvas.width - secondaryImagePadding * 2, secondaryImageHelperCanvas.height - secondaryImagePadding * 2
+			);
+			
+			secondaryImageHelperContext.globalCompositeOperation = "destination-in";
+			
+			secondaryImageHelperContext.beginPath();
+			secondaryImageHelperContext.arc(
+				secondaryImageHelperCanvas.width / 2,
+				secondaryImageHelperCanvas.height / 2,
+				(secondaryImageHelperCanvas.width - 2 * secondaryImagePadding) / 2, // Radius
+				0,
+				2 * Math.PI,
+				false
+			);
+			secondaryImageHelperContext.closePath();
+			
+			secondaryImageHelperContext.fill();
+			
+			secondaryImageHelperContext.globalCompositeOperation = "source-over";
+			
+			this.context.drawImage(
+				secondaryImageHelperCanvas,
+				backgroundRectangleOffsetSides,
+				(
+					this.canvas.height
+					- backgroundRectangleOffsetBottom
+					- secondaryImageHelperCanvas.height
+				)
+			);
+		}
+		
+		// Create logo image
+		function drawLogoImage(image) {
+			const logoHeight = image.height * (logoWidth / image.width);
+			
+			classRef.context.drawImage(
+				image,
+				(
+					classRef.canvas.width
+					- logoOffsetSide
+					- logoWidth
+				),
+				(
+					classRef.canvas.height
+					- logoOffsetBottom
+					- logoHeight
+				),
+				logoWidth, logoHeight
+			);
+		}
+		
+		if (this.logoImage === null) {
+			const logoImageLoadPromise = new Promise(
+				resolve => {
+					let logoImage = new Image();
+					
+					logoImage.onload = function() {
+						drawLogoImage(this);
+						
+						resolve();
+					}
+					
+					// See if we're using the light or dark version
+					if (classRef.backgroundLightness > 207) {
+						logoImage.src = classRef.lightLogoDefaultSource;
+					} else {
+						logoImage.src = classRef.darkLogoDefaultSource;
+					}
+				}
+			);
+			
+			await logoImageLoadPromise;
+		} else {
+			drawLogoImage(this.logoImage);
+		}
+		
+		if (this.requesterText !== "") {
+			// https://newspaint.wordpress.com/2014/05/22/writing-rotated-text-on-a-javascript-canvas/
+			// Thanks to newspaint!
+			
+			this.context.save();
+
+			this.context.translate(this.canvas.width - 1, 0);
+
+			this.context.rotate(3 * Math.PI / 2);
+
+			let requesterFontSize = Math.ceil(this.canvas.width * 0.015);
+			
+			do {
+				this.context.font = `${this.primaryFontStyle} ${requesterFontSize}px ${this.primaryFont}`;
+				
+				if (
+					this.context.measureText(this.requesterText).width
+					> this.canvas.height * 0.97
+				) {
+					requesterFontSize -= 2;
+					this.context.font = `${this.primaryFontStyle} ${requesterFontSize}px ${this.primaryFont}`;
+				}
+			} while (
+				this.context.measureText(this.requesterText).width
+				> this.canvas.height * 0.97
+			);
+			
+			this.context.fillStyle = this.requesterTextColor;
+
+			this.context.textAlign = "left";
+
+			this.context.globalAlpha = 0.6;
+			this.context.fillText(
+				this.requesterText,
+				-this.canvas.height * 0.985, -this.canvas.width * 0.985 + requesterFontSize
+			);
+			this.context.globalAlpha = 1;
+			
+			this.context.restore();
+		}
+		this.finalDrawHook();
+		this.stickerDrawHook();
+		
+		this.redrawing = false;
+	}
+	
+	// Color schemes
+	async setPrimaryColorScheme(scheme, skipRedraw = false) {
+		switch (scheme) {
+			case "black-on-white":
+				this.foregroundColor = "#f6cb03";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#1d1d1b";
+				this.primaryTextHighlightColor = "#f6cb03";
+
+				this.nameBackgroundColor = "#1d1d1b";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "white-on-black":
+				this.foregroundColor = "#f6cb03";
+				this.backgroundColor = "#1d1d1b";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#f6cb03";
+
+				this.nameBackgroundColor = "#ffffff";
+				this.nameTextColor = "#000000";
+
+				break;
+			case "forum-black-on-white":
+				this.foregroundColor = "#962a51";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#962a51";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "forum-white-on-purple":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#962a51";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "zeleni-volary-bystrc-most-black-on-white":
+				this.foregroundColor = "#00ad43";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#00ad43";
+
+				this.nameBackgroundColor = "#00ad43";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "zeleni-volary-bystrc-most-white-on-green":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#00ad43";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "spolecne-s-piraty-black-on-white":
+				this.foregroundColor = "#21274e";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#21274e";
+
+				this.nameBackgroundColor = "#21274e";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "spolecne-s-piraty-white-on-blue":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#21274e";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "louny-spolecne-black-on-white":
+				this.foregroundColor = "#3e2a5b";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#3e2a5b";
+
+				this.nameBackgroundColor = "#3e2a5b";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "louny-spolecne-white-on-purple":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#3e2a5b";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "litomerice-blue-on-white":
+				this.foregroundColor = "#123172";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#123172";
+
+				this.nameBackgroundColor = "#123172";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "litomerice-white-on-blue":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#123172";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "stranane-gray-on-yellow":
+				this.foregroundColor = "#ffd500";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#4d4d4d";
+				this.primaryTextHighlightColor = "#ffd500";
+
+				this.nameBackgroundColor = "#ffd500";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "stranane-yellow-on-white":
+				this.foregroundColor = "#4d4d4d";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#ffd500";
+				this.primaryTextHighlightColor = "#4d4d4d";
+
+				this.nameBackgroundColor = "#ffd500";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "stranane-white-on-yellow":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#ffd500";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "prusanky-black-on-yellow":
+				this.foregroundColor = "#962a51";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#962a51";
+
+				this.nameBackgroundColor = "#962a51";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "prusanky-yellow-on-white":
+				this.foregroundColor = "#ffd500";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#ffd500";
+
+				this.nameBackgroundColor = "#ffd500";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "prusanky-white-on-yellow":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#ffd500";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "ujezd-green-on-white":
+				this.foregroundColor = "#8ed4a3";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#8ed4a3";
+
+				this.nameBackgroundColor = "#8ed4a3";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "ujezd-white-on-green":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#8ed4a3";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "cssd-red-on-black":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#000000";
+
+				this.primaryTextColor = "#ff0000";
+				this.primaryTextHighlightColor = "#ffffff";
+
+				this.nameBackgroundColor = "#ff0000";
+				this.nameTextColor = "#000000";
+
+				break;
+			case "cssd-black-on-red":
+				this.foregroundColor = "#e63812";
+				this.backgroundColor = "#ff0000";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#e63812";
+
+				this.nameBackgroundColor = "#e63812";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "jilemnice-purple-on-black":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#962a51";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "jilemnice-black-on-purple":
+				this.foregroundColor = "#6e1646";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#6e1646";
+
+				this.nameBackgroundColor = "#6e1646";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "novarole-white-on-green":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#6e1646";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "novarole-green-on-white":
+				this.foregroundColor = "#a9ce2d";
+				this.backgroundColor = "#ffffff";
+
+				this.primaryTextColor = "#000000";
+				this.primaryTextHighlightColor = "#a9ce2d";
+
+				this.nameBackgroundColor = "#a9ce2d";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "novarole-green-on-black":
+				this.foregroundColor = "#ffffff";
+				this.backgroundColor = "#a9ce2d";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#000000";
+
+				this.nameBackgroundColor = "#000000";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			case "zeleni-melnik-yellow-name-rect":
+				this.foregroundColor = "#f6cb03";
+				this.backgroundColor = "#1d1d1b";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#f6cb03";
+
+				this.nameBackgroundColor = "#962a51";
+				this.nameTextColor = "#ffffff";
+
+				break;
+			default:
+				this.foregroundColor = "#f6cb03";
+				this.backgroundColor = "#1d1d1b";
+
+				this.primaryTextColor = "#ffffff";
+				this.primaryTextHighlightColor = "#f6cb03";
+
+				this.nameBackgroundColor = "#ffffff";
+				this.nameTextColor = "#000000";
+
+				throw new Error("This scheme does not exist.");
+				break;
+		}
+		
+		this.requesterTextColor = this.primaryTextColor;
+		
+		if (!skipRedraw) {
+			await this.redrawCanvas();
+		}
+	}
+	
+	// Secondary image
+	async setSecondaryImageFromInput(imageInput, skipRedraw = false) {
+		if (imageInput.files.length == 0) {
+			return;
+		}
+		
+		const readPromise = new Promise(
+			resolve => {
+				const fileReader = new FileReader();
+				
+				let classRef = this;
+				
+				fileReader.onloadend = function(event) {
+					classRef.secondaryImage = new Image();
+					
+					classRef.secondaryImage.onload = function() {
+						if (!skipRedraw) {
+							classRef.redrawCanvas();
+						}
+						
+						resolve();
+					}
+					
+					classRef.secondaryImage.src = event.target.result;
+				}
+				
+				fileReader.readAsDataURL(imageInput.files[0]);
+			}
+		);
+		
+		await readPromise;
+	}
+}
diff --git a/generator/static/js/ui.js b/generator/static/js/ui.js
index ca3e5506c06fd2633c57950639c85fcb1eec3451..3743692f854e5ffd6b708ef8ae9c6398ed8f09e6 100644
--- a/generator/static/js/ui.js
+++ b/generator/static/js/ui.js
@@ -5,6 +5,7 @@ const templateTypes = {
 	"bottom-slogan-gradient": BottomSloganGradient,
 	"bottom-slogan-gradient-vertical-logo": BottomSloganGradientVerticalLogo,
 	"bottom-slogan-person": BottomSloganPerson,
+	"bottom-slogan-quote": BottomSloganQuote,
 	"bottom-slogan-full-width": BottomSloganFullWidth,
 	"bottom-slogan-vertical-logo": BottomSloganVerticalLogo,
 	"left-long-text": LeftLongTextTemplate,
@@ -1612,6 +1613,9 @@ $(".colorPickSelector").html(`<option
 	<option
 		value=\"#838383\"
 	>Šedá 6</option>
+	<option
+		value=\"#1D1D1B\"
+	>Šedá 7</option>
 	<option
 		value=\"#962A51\"
 	>Rudá 1</option>
@@ -1696,6 +1700,9 @@ $(".colorPickSelector").html(`<option
 	<option
 		value=\"#FFDD55\"
 	>Žlutá 11</option>
+	<option
+		value=\"#F6CB03\"
+	>Žlutá 12</option>
 	<option
 		value=\"#CDDE87\"
 	>Limetková 1</option>
diff --git a/generator/templates/generator.html b/generator/templates/generator.html
index 9336e97866240f4c32ea9ceadd328d0da2ba8665..b4073532632070226933456fbf8844ead773c550 100644
--- a/generator/templates/generator.html
+++ b/generator/templates/generator.html
@@ -55,6 +55,10 @@
 			type="text/javascript"
 			src="{{ url_for('static', filename='js/templates/bottom-slogan-person.js') }}"
 		></script>
+		<script
+			type="text/javascript"
+			src="{{ url_for('static', filename='js/templates/bottom-slogan-quote.js') }}"
+		></script>
 		
 		<script
 			type="text/javascript"
@@ -464,7 +468,7 @@
 					<br>
 					
 					<small>
-						Generátor s ♥ vytvořil <a href="https://toho.neocities.org" target="_blank" rel="nofollow">Tomáš Valenta</a>
+						Generátor s ♥ vytvořil <a href="https://blog.imaniti.org" target="_blank" rel="nofollow">Tomáš Valenta</a>
 						pod svobodnou licencí <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" target="_blank">AGPLv3</a>.
 					</small>
 				</section>
@@ -492,6 +496,10 @@
 								data-image-source="static/images/examples/bottom-slogan-person.png"
 								data-template-type="bottom-slogan-person"
 							>Velký spodní slogan, podobný nalodění</option>
+							<option
+								data-image-source="static/images/examples/bottom-slogan-quote.png"
+								data-template-type="bottom-slogan-quote"
+							>Velký spodní slogan, citát</option>
 							
 							<option
 								data-image-source="static/images/examples/left-long-text.png"