diff --git a/css/main.css b/css/main.css
index 693ca2448273e5c453613b108b4c7fcb873b79f0..57f548b397795fc57b5a1b8e66fb2e6901b1d164 100644
--- a/css/main.css
+++ b/css/main.css
@@ -156,6 +156,16 @@ article#tools-list-buttons {
   height: 2.5rem;
 }
 
+#helpDialog ul {
+  list-style-type: none;
+  padding: 0;
+}
+
+#helpDialog ul > li > span.helpControlText {
+  position: absolute;
+  left: 3rem;
+}
+
 /* Zdog */
 
 .zdog-canvas {
diff --git a/main.js b/main.js
index a2cc940251b36fc07bc18ffce073de60d898a643..b0e52e8e592db55536dd4f9aff81e88e976b5136 100644
--- a/main.js
+++ b/main.js
@@ -9,6 +9,20 @@ import * as Zdog from "zdog";
 import "@fortawesome/fontawesome-free/css/fontawesome.css";
 import "@fortawesome/fontawesome-free/css/solid.css";
 
+var aboutText = `
+</h1>
+<p>Version: ${ import.meta.env.VITE_APP_DATE }
+(${ import.meta.env.VITE_APP_HASH })</p>
+`;
+if (import.meta.env.VITE_APP_BRANCH == "dev") {
+  aboutText = `
+  <i class="fa-solid fa-kiwi-bird fa-bounce"></i> BETA</h1>
+  <p>Version: ${ import.meta.env.VITE_APP_DATE }
+  (${ import.meta.env.VITE_APP_BRANCH }
+  ${ import.meta.env.VITE_APP_HASH })</p>
+  `;
+}
+
 document.querySelector("#app").innerHTML = `
 <main>
   <section id="viewer">
@@ -106,15 +120,14 @@ document.querySelector("#app").innerHTML = `
 
 <!-- Dialogs -->
 <dialog id="helpDialog">
-  <h1>Tailorbird 3D</h1>
-  <p>${ new Date().toISOString() }</p>
-  <h2>Controls</h2>
+  <h1>Tailorbird 3D ${ aboutText }
+  <h2><i class="fa-solid fa-keyboard"></i> Controls</h2>
   <p>
    <ul>
-    <li>Zoom: Scroll wheel</li>
-    <li>Drag: Rotate horizontally</li>
-    <li>Shift+Drag: Rotate vertically</li>
-    <li>Opt/Alt+Drag: Move</li>
+    <li><i class="fa-solid fa-magnifying-glass"></i> <span class="helpControlText">Zoom: Scroll wheel</span></li>
+    <li><i class="fa-solid fa-left-right"></i> <span class="helpControlText">Rotate horizontally: Drag</span></li>
+    <li><i class="fa-solid fa-up-down"></i> <span class="helpControlText">Rotate vertically: Shift+Drag</span></li>
+    <li><i class="fa-solid fa-up-down-left-right"></i> <span class="helpControlText">Move: Opt/Alt+Drag</span></li>
    </ul>
   </p>
   <form method="dialog">
@@ -874,9 +887,9 @@ G28
 
   document
     .getElementById("settingsDialog")
-    .addEventListener("close", function onClose() {
+    .addEventListener("close", function onClose(e) {
       // Check if Apply button was pressed
-      if (event.target.returnValue != "apply") return;
+      if (e.target.returnValue != "apply") return;
       const data = new FormData(document.querySelector("#settingsForm"));
 
       // Grid display
@@ -918,18 +931,18 @@ G28
 
   document
     .getElementById("saveDialog")
-    .addEventListener("close", function onClose() {
+    .addEventListener("close", function onClose(e) {
       // Check if Load button was pressed
-      if (event.target.returnValue != "save") return;
+      if (e.target.returnValue != "save") return;
       const inputEl = document.getElementById("saveDialogInput");
       saveProject(inputEl.value);
     });
 
   document
     .getElementById("loadDialog")
-    .addEventListener("close", function onClose() {
+    .addEventListener("close", function onClose(e) {
       // Check if Load button was pressed
-      if (event.target.returnValue != "load") return;
+      if (e.target.returnValue != "load") return;
       const inputEl = document.getElementById("loadDialogInput");
       const saveInputEl = document.getElementById("saveDialogInput");
       loadProject(inputEl.value);
@@ -939,9 +952,9 @@ G28
 
   document
     .getElementById("helpDialog")
-    .addEventListener("close", function onClose() {
+    .addEventListener("close", function onClose(e) {
       // Check if Load button was pressed
-      switch (event.target.returnValue) {
+      switch (e.target.returnValue) {
         case "example1":
           window.currentProject = getPresetModelVase();
           break;
@@ -955,9 +968,9 @@ G28
 
   document
     .getElementById("addLineDialog")
-    .addEventListener("close", function onClose() {
+    .addEventListener("close", function onClose(e) {
       // Check if Add button was pressed
-      if (event.target.returnValue != "add") return;
+      if (e.target.returnValue != "add") return;
 
       let inputX = document.getElementById("addLineInputX");
       let inputY = document.getElementById("addLineInputY");
@@ -1024,9 +1037,9 @@ G28
 
   document
     .getElementById("addArcDialog")
-    .addEventListener("close", function onClose() {
+    .addEventListener("close", function onClose(e) {
       // Check if Add button was pressed
-      if (event.target.returnValue != "add") return;
+      if (e.target.returnValue != "add") return;
 
       const size = document.getElementById("addArcInputSize");
       const data = new FormData(document.querySelector("#addArcForm"));
@@ -1048,4 +1061,8 @@ window.onload = function () {
   window.selectedListEntries = [];
   initIllo();
   initEventListeners();
+  if (localStorage.getItem("splashSeen") !== "1") {
+    localStorage.setItem("splashSeen", "1");
+    document.getElementById("helpDialog").showModal();
+  }
 };
diff --git a/vite.config.js b/vite.config.js
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..431d05d09a376068f129faee8109233134d7c4ad 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -0,0 +1,14 @@
+import { defineConfig } from 'vite'
+import * as child from "child_process";
+
+const commitDate = new Date(child.execSync('git log -1 --format=%cI').toString().trimEnd()).toDateString();
+const branchName = child.execSync('git rev-parse --abbrev-ref HEAD').toString().trimEnd();
+const commitHash = child.execSync('git rev-parse --short HEAD').toString().trimEnd();
+
+export default defineConfig({
+    define: {
+        'import.meta.env.VITE_APP_DATE': JSON.stringify(commitDate),
+        'import.meta.env.VITE_APP_BRANCH': JSON.stringify(branchName),
+        'import.meta.env.VITE_APP_HASH': JSON.stringify(commitHash),
+    }
+});
\ No newline at end of file