diff --git a/.editorconfig b/.editorconfig
index e100c8b358941f02aed25a61b9a3344bbcc86363..0f356b69da2004822321df807706a555dffd5bad 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -6,7 +6,7 @@ end_of_line = lf
 trim_trailing_whitespace = true
 insert_final_newline = true
 
-[*.{json,less,ts,html.j2}]
+[*.{json,less,ts,html.j2,css}]
 indent_style = tab
 indent_size = 4
 
diff --git a/examples/static/schild.css b/examples/static/schild.css
index 1616d564c1d565154eff6c56893106a59532c644..44cf298f895abb3ea7dcc3c95bc7fa66aaafd40b 100644
--- a/examples/static/schild.css
+++ b/examples/static/schild.css
@@ -1,83 +1,86 @@
 @page {
-    size: a4 landscape;
-    margin: 50px;
+	size: a4 landscape;
+	margin: 50px;
 }
 
 * {
-    box-sizing: border-box;
+	box-sizing: border-box;
 }
 
 body {
-    font-size: 48px;
-    font-family: "Noto Sans", sans-serif;
-    padding: 0;
-    margin: 0;
-    display: flex;
-    flex-direction: column;
-    @media not print {
-	/* This magic constant approximately corresponds to 48px at A4 size, but scales
-	 * with the viewport/iframe size
-	 */
-	font-size: 4.27426536064114vw;
-	padding: 4.27426536064114vw;
-	width: 100vw;
-	height: 100vh;
-	max-width: 100vw;
-	max-height: 100vh;
-    }
+	font-size: 48px;
+	font-family: "Noto Sans", sans-serif;
+	padding: 0;
+	margin: 0;
+	background-color: #fff;
+	color: #000;
+	display: flex;
+	flex-direction: column;
+
+	@media not print {
+		/* This magic constant approximately corresponds to 48px at A4 size, but scales
+		 * with the viewport/iframe size
+		 */
+		font-size: 4.27426536064114vw;
+		padding: 4.27426536064114vw;
+		width: 100vw;
+		height: 100vh;
+		max-width: 100vw;
+		max-height: 100vh;
+	}
 }
 
 main {
-    flex-grow: 1;
-    max-height: 11.3em;
+	flex-grow: 1;
+	max-height: 11.3em;
 }
 
 img {
-    max-width: 100%;
-    max-height: 100%;
-    object-fit: contain;
-    display: block;
+	max-width: 100%;
+	max-height: 100%;
+	object-fit: contain;
+	display: block;
 }
 
 #logo {
-    width: 15%;
+	width: 15%;
 }
 
 footer {
-    font-size: 0.5em;
-    display: flex;
-    align-items: flex-end;
+	font-size: 0.5em;
+	display: flex;
+	align-items: flex-end;
 }
 
 #footer {
-    flex-grow: 1;
+	flex-grow: 1;
 }
 
 h1 {
-    margin-top: 0;
+	margin-top: 0;
 }
 
 p {
-    margin-top: 0;
-    margin-bottom: 0;
+	margin-top: 0;
+	margin-bottom: 0;
 }
 
 .container {
-    column-count: 2;
-    column-fill: balance;
+	column-count: 2;
+	column-fill: balance;
 }
 
 .container > img,
 .container > svg {
-    max-width: 100%;
-    max-height: 8em;
-    display: block;
-    margin-left: auto;
-    margin-right: auto;
+	max-width: 100%;
+	max-height: 8em;
+	display: block;
+	margin-left: auto;
+	margin-right: auto;
 }
 
 .box, svg {
-    width: 100%;
-    margin: 0;
-    padding: 0;
+	width: 100%;
+	margin: 0;
+	padding: 0;
 }
diff --git a/frontend/src/main.less b/frontend/src/main.less
index 89c0e5389c3cf04c199ab00d8964d84ca7b59c06..966bf21fdf405d3ba15668e8397d989ad43d8a92 100644
--- a/frontend/src/main.less
+++ b/frontend/src/main.less
@@ -1,5 +1,12 @@
 // the threshold at which we consider the screen "mobile"
 @mobile_threshold: 700px;
+// the threshold at which we consider the screen "wide", i.e. display the preview on the
+// side instead of at the bottom
+@wide_threshold: 1700px;
+// the border around the options in the fieldset-select-like things
+@option_border: .3rem;
+// the minimum size of the left area in the form layout
+@label-width: 90px;
 
 * {
 	box-sizing: border-box;
@@ -13,6 +20,7 @@ body {
 	// adjust colors for light theme here
 	--bg: #fff;
 	--fg: #000;
+	--fg-dark: #bbb;
 	--accent: #80f;
 	--accent2: #c4f;
 
@@ -20,10 +28,39 @@ body {
 		// adjust colors for dark theme here
 		--bg: #222;
 		--fg: #fff;
+		--fg-dark: #888;
 	}
+}
+
+@inputs: ~'input[type = "text"], input[type = "number"], textarea, select';
+@buttons: ~'input[type = "submit"], button, a.button';
+
+body, @{inputs}, @{buttons} {
+	&, &:hover, &:visited {
+		background-color: var(--bg);
+		color: var(--fg);
+		// ja, user agents haben lack gesoffen
+		font-size: 1rem;
+	}
+}
 
-	background-color: var(--bg);
-	color: var(--fg);
+@{inputs}, @{buttons}, fieldset {
+	border: .15rem solid var(--fg-dark);
+	border-radius: .25rem;
+}
+
+@{inputs} {
+	padding: .2rem .3rem;
+}
+
+@{buttons} {
+	padding: .2rem .6rem;
+
+	&:hover {
+		border-color: var(--accent2);
+		cursor: pointer;
+		text-decoration: none;
+	}
 }
 
 a {
@@ -127,84 +164,126 @@ main {
 	}
 }
 
+.section-container {
+	display: grid;
+	grid-gap: 1rem;
+	grid-template-columns: 1fr;
+
+	.section {
+		grid-column-start: 1;
+	}
+
+	@media screen and (min-width: @wide_threshold) {
+		grid-template-columns: 1fr 1fr;
+
+		.preview-section {
+			grid-column-start: 2;
+			grid-row: 1/span 3;
+		}
+	}
+}
+
 .preview {
-	width: min(95vw, 100rem);
 	/* A4 aspect ratio: √2:1 */
 	aspect-ratio: 1.4142135623730951;
-
-	background-color: #fff;
-	color: #000;
 }
 
-.preview-small {
-	width: 15rem;
+.preview-container .preview {
+	width: 100%;
 }
 
-.preview-label {
-	place-self: center;
-}
+// this is the form layout row container thingy
+.box {
+	display: grid;
+	grid-template-columns: min(@label-width, auto) 1fr;
+	align-items: baseline;
 
-form {
-	display: inline-block;
-}
+	label.for-text {
+		display: inline-block;
+		justify-self: end;
+		font-size: 1.1rem;
+	}
 
-@label-padding: 90px;
+	input[type = "text"], textarea {
+		justify-self: stretch;
+	}
 
-label.for-text {
-	display: inline-block;
-	min-width: @label-padding;
-	text-align: right;
+	textarea {
+		height: 5rem;
+	}
 }
 
-input[type="text"], textarea {
-	width: 300px;
+// this is the form layout row with buttons in it
+.buttons {
+	display: flex;
+	justify-content: flex-end;
+	align-items: stretch;
 }
 
-textarea {
-	height: 5em;
-	vertical-align: top;
+.box, .buttons {
+	margin: .5rem 0;
+	gap: 1ch;
 }
 
-fieldset {
+// these are the fieldsets containing select-like options modeled with radio buttons
+.select {
 	display: flex;
 	flex-wrap: wrap;
-}
+	gap: 2 * @option_border;
 
-fieldset > div {
-	display: flex;
-	gap: 0.5rem;
-	flex-direction: column;
-}
+	.option {
+		display: flex;
+		flex-direction: column;
+		gap: .5rem;
 
-.imageselect > div {
-	width: 10rem;
-	display: flex;
-	gap: 0.5rem;
-}
+		.preview {
+			width: 15rem;
+			cursor: pointer;
+		}
 
-fieldset label {
-	flex-grow: 1;
-}
+		.preview-label {
+			place-self: center;
+		}
 
-.imageselect img {
-	width: 100%;
-	background-color: #fff;
-}
+		img {
+			width: 10rem;
+			background-color: #fff;
+		}
 
-fieldset input {
-	display: none;
-}
+		.option-border {
+			border: @option_border solid var(--fg-dark);
+			border-radius: 3 * @option_border;
+
+			// iframe's behave nicely
+			&.preview {
+				padding: @option_border;
+			}
+
+			// label>img doesn't
+			& > img {
+				border: @option_border solid var(--bg);
+				border-radius: 2 * @option_border;
+				object-fit: contain;
+			}
+		}
 
-fieldset img,
-fieldset iframe,
-.preview-small {
-	border: 3px solid lightgray;
-	border-radius: 10px;
-}
+		input[type = "radio"] {
+			display: none;
 
-input[type="radio"]:checked {
-	& + label > img,
-	& + iframe {
-		border:3px solid red;
+			&:checked + .option-border {
+				border-color: var(--accent2);
+			}
+		}
+
+		label {
+			flex-grow: 1;
+			// firefox hat hier lack gesoffen und erfindet 5px wenn das hier block oder
+			// inline ist
+			display: flex;
+		}
+	}
+
+	input[type = "radio"] {
+		display: none;
 	}
 }
diff --git a/frontend/src/main.ts b/frontend/src/main.ts
index 23650e5fde1a929fa2a497f0a619fdb4e486688f..6a987728de755d1826356c93bb8e57640c1028c7 100644
--- a/frontend/src/main.ts
+++ b/frontend/src/main.ts
@@ -1,7 +1,5 @@
 import './main.less';
 
-console.log("Hello World");
-
 function onInputHandler(event: Event) {
 	const preview = document.getElementById('preview') as HTMLIFrameElement;
 	const previewDoc = preview.contentDocument as Document;
@@ -12,9 +10,30 @@ function onInputHandler(event: Event) {
 
 window.addEventListener("load", () => {
 	if (document.getElementById('preview')) {
-		for (let el of document.getElementsByClassName('input-dispatch')) {
+		for (const el of document.getElementsByClassName('input-dispatch')) {
 			console.log(el);
 			el.addEventListener('input', onInputHandler);
 		}
+
+		for (const op of document.querySelectorAll('.option .preview')) {
+			console.log(op);
+			const input_id = (op as HTMLElement).dataset.for;
+			if (!input_id) {
+				console.error("Missing data-for attribute for", op);
+				continue;
+			}
+			const input = document.getElementById(input_id);
+			if (!input || input === null) {
+				console.error("Unable to find input for", op);
+				continue;
+			}
+
+			const handler = (_: Event) => {
+				console.log("clicked");
+				(input as HTMLInputElement).checked = true;
+			};
+			op.addEventListener('click', handler);
+			(op as HTMLIFrameElement).contentDocument?.addEventListener('click', handler);
+		}
 	}
 });
diff --git a/schilder2000/templates/schild.html.j2 b/schilder2000/templates/schild.html.j2
index f4136d6baa39199ec85ca26b476e4c4bf6a5be9b..615a8781823de4c567601591b6f50f8a4939d252 100644
--- a/schilder2000/templates/schild.html.j2
+++ b/schilder2000/templates/schild.html.j2
@@ -28,111 +28,114 @@
 {%- endblock title %}
 
 {% block main -%}
-	<section>
-	{%- with messages = get_flashed_messages() -%}
-		{%- if messages -%}
-			<ul class="flashes">
-				{%- for m in messages -%}
-					<li>{{ m }}</li>
-				{%- endfor -%}
-			</ul>
-		{%- endif -%}
-	{%- endwith -%}
-	</section>
+	<div class="section-container">
+		<div class="section">
+			{%- with messages = get_flashed_messages() -%}
+				{%- if messages -%}
+					<ul class="flashes">
+						{%- for m in messages -%}
+							<li>{{ m }}</li>
+						{%- endfor -%}
+					</ul>
+				{%- endif -%}
+			{%- endwith -%}
+		</div>
 
-	<section>
-	<form method="post" action="">
-		{{ form.csrf_token }}
+		<div class="section">
+			<form method="post" action="">
+				{{ form.csrf_token }}
 
-		{{ render_field(form.title, "input-dispatch") }}
-		{{ render_field(form.text, "input-dispatch") }}
+				{{ render_field(form.title, "input-dispatch") }}
+				{{ render_field(form.text, "input-dispatch") }}
 
-		<fieldset class="templateselect">
-			<legend>Vorlage</legend>
-			{%- for t in form.template.choices -%}
-				<div>
-					<input
-						type="radio"
-						name="template"
-						id="template:{{ t.name }}"
-						value="{{ t.name }}"
-						{% if t.name == (schild | default(None)).template -%}
-							checked
-						{%- endif -%}
-					/>
-					<iframe
-						class="preview preview-small"
-						src="{{ url_for('instance.sample_html', template=t.name) }}"
-						id="template-preview:{{ t.name }}"
-					>
-					</iframe>
-					<label for="template:{{ t.name }}" class="preview-label">
-						{{ t.description or t.name }}
-					</label>
-				</div>
-			{% endfor %}
-		</fieldset>
+				<fieldset class="select templateselect">
+					<legend>Vorlage</legend>
+					{%- for t in form.template.choices -%}
+						<div class="option">
+							<input
+								type="radio"
+								name="template"
+								id="template:{{ t.name }}"
+								value="{{ t.name }}"
+								{% if t.name == (schild | default(None)).template -%}
+									checked
+								{%- endif -%}
+							/>
+							<iframe
+								class="preview option-border"
+								src="{{ url_for('instance.sample_html', template=t.name) }}"
+								id="template-preview:{{ t.name }}"
+								data-for="template:{{ t.name }}"
+							>
+							</iframe>
+							<label for="template:{{ t.name }}" class="preview-label">
+								{{ t.description or t.name }}
+							</label>
+						</div>
+					{% endfor %}
+				</fieldset>
 
-		<fieldset class="imageselect">
-			<legend>Bild</legend>
-			{%- for img in form.image.choices -%}
-				<div>
-					<input
-						type="radio"
-						name="image"
-						id="img:{{ img }}"
-						value="{{ img }}"
-						{% if img == (schild | default(None)).image -%}
-							checked
-						{%- endif -%}
-					/>
-					<label for="img:{{ img }}">
-						<img src="{{ url_for('instance.static', filename='img/'+img) }}" title="{{ img }}" />
-					</label>
-				</div>
-			{%- endfor -%}
-		</fieldset>
-
-		<div class="box">
-			{%- if schild -%}
-				<input type="submit" value="Speichern" />
-				<input
-					type="submit"
-					formaction="{{ url_for('views.create') }}"
-					value="Neues Schild erstellen"
-				/>
-			{%- else -%}
-				<input type="submit" value="Schild erstellen" />
-			{%- endif -%}
-		</div>
-	</form>
-	</section>
+				<fieldset class="select imageselect">
+					<legend>Bild</legend>
+					{%- for img in form.image.choices -%}
+						<div class="option">
+							<input
+								type="radio"
+								name="image"
+								id="img:{{ img }}"
+								value="{{ img }}"
+								{% if img == (schild | default(None)).image -%}
+									checked
+								{%- endif -%}
+							/>
+							<label for="img:{{ img }}" class="option-border">
+								<img src="{{ url_for('instance.static', filename='img/'+img) }}" title="{{ img }}" />
+							</label>
+						</div>
+					{%- endfor -%}
+				</fieldset>
 
-	{%- if schild %}
-		<div>
-			<a href="{{ url_for('instance.schild_pdf', ident=schild.ident) }}">
-				Als PDF anzeigen
-			</a>
+				<div class="buttons">
+					{%- if schild -%}
+						<input type="submit" value="Speichern" />
+						<input
+							type="submit"
+							formaction="{{ url_for('views.create') }}"
+							value="Neues Schild erstellen"
+						/>
+					{%- else -%}
+						<input type="submit" value="Schild erstellen" />
+					{%- endif -%}
+				</div>
+			</form>
 		</div>
 
-		<section><form method="post" action="{{ url_for('.print', ident=schild.ident) }}">
-			{%- for field in printform -%}
-				{{ render_field(field) }}
-			{%- endfor -%}
-
-			<input type="submit" value="Drucken" />
-		</form></section>
+		{%- if schild %}
+			<div class="section">
+				<form method="post" action="{{ url_for('.print', ident=schild.ident) }}">
+					{%- for field in printform -%}
+						{{ render_field(field) }}
+					{%- endfor -%}
 
+					<div class="buttons">
+						<a class="button" href="{{ url_for('instance.schild_pdf', ident=schild.ident) }}">
+							Als PDF anzeigen
+						</a>
+						<input type="submit" value="Drucken" />
+					</div>
+				</form>
+			</div>
 
-		<div>
-			<h2>Vorschau</h2>
-			<div class="preview-container" id="preview-container">
-				<iframe
-					class="preview"
-					id="preview"
-					src="{{ url_for('instance.schild_html', ident=schild.ident) }}">
-				</iframe>
+			<div class="section preview-section">
+				<h2>Vorschau</h2>
+				<div class="preview-container" id="preview-container">
+					<iframe
+						class="preview"
+						id="preview"
+						src="{{ url_for('instance.schild_html', ident=schild.ident) }}">
+					</iframe>
+				</div>
 			</div>
-		</div>
-	{% endif %}
+		{% endif %}
+	</div>
 {% endblock main %}