diff --git a/src/content/kontakt/erfolg.md b/src/content/kontakt/erfolg.md
deleted file mode 100644
index bc682b0..0000000
--- a/src/content/kontakt/erfolg.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-layout: layouts/page.njk
----
-
-# Erfolgreich abgesendet
-
-Vielen Dank, wir haben deine Anfrage entgegengenommen und werden uns bei dir
-melden. Du solltest in Kürze per E-Mail eine entsprechende Bestätigung erhalten.
diff --git a/src/content/kontakt/fertig.md b/src/content/kontakt/fertig.md
new file mode 100644
index 0000000..75886db
--- /dev/null
+++ b/src/content/kontakt/fertig.md
@@ -0,0 +1,35 @@
+---
+layout: layouts/page.njk
+extraStylesheets: ['finish']
+---
+
+# Es hat geklappt!
+
+
+
+**Wir stöpseln das** – Vielen Dank, wir haben deine Anfrage
+entgegengenommen und werden uns bei dir melden. Du solltest in Kürze per E-Mail
+eine entsprechende Bestätigung erhalten.
diff --git a/src/styles/finish.scss b/src/styles/finish.scss
new file mode 100644
index 0000000..2fd96d4
--- /dev/null
+++ b/src/styles/finish.scss
@@ -0,0 +1,124 @@
+/**
+ * finish.scss
+ * This is the stylesheet for the finish page that is displayed after submiting
+ * a contact form.
+ */
+
+@use 'sass:list';
+@use 'lib/colors';
+@use 'lib/layout';
+@use 'lib/motion';
+
+.finish-hero {
+ @keyframes finish-hero {
+ 0% { stroke-width: 3px; }
+ 10% { stroke-width: 3px; }
+ 20% { stroke-width: 5px; }
+ 60% { stroke-width: 5px; }
+ 100% { stroke-width: 3px; }
+ }
+
+ display: block;
+ height: 15vmin;
+ margin: layout.$huge-gap auto;
+ overflow: visible;
+ stroke-linecap: round;
+ stroke-miterlimit: 10;
+ animation: motion.$prominent 0s 1 normal both running finish-hero;
+
+ > .stroke-gradient {
+ $idle-color: colors.$gray-900;
+ $colors: [
+ $idle-color
+ $idle-color
+ $idle-color
+ colors.$blue-500
+ colors.$teal-500
+ colors.$yellow-500
+ colors.$teal-500
+ colors.$gray-300
+ colors.$yellow-500
+ colors.$blue-500
+ colors.$gray-300
+ $idle-color
+ $idle-color
+ $idle-color
+ ];
+
+ @for $i from 1 through 4 {
+ > stop:nth-of-type(#{$i}) {
+ @keyframes finish-stroke-gradient-#{$i} {
+ 0% { stop-color: $idle-color; }
+ 15% { stop-color: $idle-color; }
+ // This is some which magic that chooses the correct colors for each
+ // stop - don't change it unless you know what you are doing! In
+ // general, the output will look something like this:
+ // : ...
+ // 20%: 4 3 2 1
+ // 25%: 5 4 3 2
+ // 35%: 6 5 4 3
+ // ...
+ // In order to achieve the 'moving' effect, we make sure that the
+ // first and last three colors match the ones we are given at 15% and
+ // 70% (before and after the core animation).
+ @for $j from 1 to list.length($colors) - 3 {
+ #{15% + $j * 5%} {
+ stop-color: list.nth($colors, 4 + $j - $i);
+ }
+ }
+ 70% { stop-color: $idle-color; }
+ 100% { stop-color: $idle-color; }
+ }
+
+ animation:
+ motion.$prominent 0s 1 normal both running finish-stroke-gradient-#{$i};
+ }
+ }
+ }
+
+ > .cable {
+ @keyframes finish-hero-cable {
+ 0% { transform: translateX(0.5rem); }
+ 20% { transform: translateX(0.5rem); }
+ 70% { transform: translateX(0.5rem); }
+ 100% { transform: none; }
+ }
+
+ animation: motion.$prominent 0s 1 normal both running finish-hero-cable;
+ }
+
+ > .plug {
+ @keyframes finish-hero-plug {
+ 0% { transform: translateX(-0.5rem); }
+ 20% { transform: translateX(-0.5rem); }
+ 70% { transform: translateX(-0.5rem); }
+ 100% { transform: none; }
+ }
+ @keyframes finish-hero-plug-transition {
+ 0% { fill: colors.$gray-900; }
+ 100% { fill: colors.$gray-600; }
+ }
+ @keyframes finish-hero-plug-idle {
+ 0% { fill: colors.$gray-600; }
+ 25% { fill: colors.$teal-600; }
+ 50% { fill: colors.$yellow-600; }
+ 75% { fill: colors.$blue-800; }
+ 100% { fill: colors.$gray-600; }
+ }
+
+ animation: motion.$prominent 0s 1 normal both running finish-hero-plug,
+ motion.$gentle 0.7s 1 normal forwards running finish-hero-plug-transition,
+ motion.$background 1s infinite normal none running finish-hero-plug-idle;
+ }
+
+ > .contacts {
+ @keyframes finish-hero-contacts {
+ 0% { transform: translateX(0rem); }
+ 20% { transform: translateX(-0.7rem); }
+ 70% { transform: translateX(-0.7rem); }
+ 100% { transform: none; }
+ }
+
+ animation: motion.$prominent 0s 1 normal both running finish-hero-contacts;
+ }
+}
diff --git a/src/styles/lib/_colors.scss b/src/styles/lib/_colors.scss
index d19bdec..0db4979 100644
--- a/src/styles/lib/_colors.scss
+++ b/src/styles/lib/_colors.scss
@@ -5,6 +5,7 @@ $gray-300: #d6d6d6;
$gray-100: #f9f9f9;
$gray-50: #ffffff;
+$teal-600: #6bc2bd;
$teal-500: #4edcca;
$teal-300: #caf4ef;
diff --git a/src/styles/lib/_motion.scss b/src/styles/lib/_motion.scss
index 208d645..14969a0 100644
--- a/src/styles/lib/_motion.scss
+++ b/src/styles/lib/_motion.scss
@@ -1,3 +1,4 @@
$subtle: 0.1s cubic-bezier(0.56, 0.03, 0.35, 0.9);
$gentle: 0.2s cubic-bezier(1, 0.11, 0.41, 0.69);
$prominent: 0.7s cubic-bezier(.45,.16,.38,.7);
+$background: 8s cubic-bezier(.45,.16,.38,.7);