diff --git a/css/art/genAI.css b/css/art/genAI.css
index 5e10009b5f18d3e53d59b16bd05bb2a83947c4e5..ddc5482cb17605044a76d698aaf1253c872fa30a 100644
--- a/css/art/genAI.css
+++ b/css/art/genAI.css
@@ -22,7 +22,6 @@
     height: 100%;
     min-width: 100px;
     min-height: 100px;
-    cursor: pointer;
     float: right;
     border: 3px hidden;
     object-fit: contain;
@@ -32,6 +31,68 @@
     display: block;
 }
 
+.ai-toolbar {
+    display: none;
+    position: absolute;
+    right: 1rem;
+    top: 1rem;
+}
+
+.ai-art-container:hover .ai-toolbar {
+    display: flex;
+    flex-direction: column;
+}
+
+
+.ai-toolbar button {
+    /* position: absolute; */
+    min-width: 2rem;
+    min-height: 2rem;
+    cursor: pointer;
+    border: none;
+    background: none;
+}
+
+.zoom-in::after {
+	font-family: "tme-fa-icons";
+	content: " \e83c"; /* Zoom in icon */
+}
+
+.refresh-icon::after {
+    font-family: "tme-fa-icons";
+	content: " \e825"; /* Refresh icon */
+}
+
+.lightbox {
+    position: fixed;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(0 0 0 / 0.2);
+}
+
+.lightbox-background {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.lightbox img {
+    max-width: 80%;
+    max-height: 80%;
+}
+
+.lightbox .close {
+    top: 4rem;
+    right: 4rem;
+    font-size: 2rem;
+    background: none;
+    position: absolute;
+    border: none;
+}
+
 @keyframes spin {
     0% {
         transform: translate(-50%, -50%) rotate(0deg);
diff --git a/src/art/artJS.js b/src/art/artJS.js
index 5fa703a85ddfbf472fbb3badaa10451086137dd8..7b50e278b5020baae9f98a4227ecfa659bc9f070 100644
--- a/src/art/artJS.js
+++ b/src/art/artJS.js
@@ -469,30 +469,101 @@ async function renderAIArt(slave, imageSize) {
 App.Art.aiArtElement = function(slave, imageSize) {
 	const container = document.createElement("div");
 	container.classList.add("ai-art-container");
+	const toolbar = document.createElement('div');
+	toolbar.classList.add('ai-toolbar');
+	container.appendChild(toolbar);
+	/** @type {HTMLButtonElement} */
+	let refreshButton;
+	/** @type {HTMLDivElement} */
+	let spinner;
+	/** @type {HTMLButtonElement} */
+	let zoomIn;
+
+	/**
+	 * @param {HTMLDivElement} toolbar
+	 * @param {HTMLDivElement} container
+	 */
+	function makeZoomIn(toolbar, container) {
+		zoomIn = document.createElement('button');
+		zoomIn.classList.add('zoom-in');
+		zoomIn.title = 'Zoom';
+		const onZoomInClick = () => {
+			const imageElement = container.querySelector('.ai-art-image');
+			if (imageElement) {
+				const lightbox = document.createElement('div');
+				lightbox.classList.add('lightbox');
+				lightbox.classList.add('ui-front');
+				// make a seperate background element so that the user can click on the image without lightbox closing
+				const lightboxBackground = document.createElement('div');
+				lightboxBackground.classList.add('lightbox-background');
+				lightboxBackground.addEventListener('click', () => {
+					console.log('background clicked');
+					lightbox.remove();
+				});
+				lightbox.appendChild(lightboxBackground);
+				// Visible button for exiting, but clicking outside of image should automatically close it anyways
+				const closeButton = document.createElement('button');
+				closeButton.classList.add('close');
+				closeButton.innerText = '✕';
+				lightboxBackground.appendChild(closeButton);
+				const lightboxImg = document.createElement('img');
+				lightboxImg.src = imageElement.getAttribute('src');
+				lightboxBackground.appendChild(lightboxImg);
+
+				document.body.appendChild(lightbox);
+			} else {
+				console.error('No image element found to lightbox');
+			}
+		};
+
+		zoomIn.addEventListener("click", onZoomInClick);
+		toolbar.appendChild(zoomIn);
+	}
+	makeZoomIn(toolbar, container);
+
+	/**
+	 * @param {HTMLDivElement} toolbar
+	 * @param {HTMLDivElement} container
+	 */
+	function makeRefreshButton(toolbar, container) {
+		refreshButton = document.createElement("button");
+		refreshButton.innerText = '⟳';
+		refreshButton.title = 'Regenerate';
+		refreshButton.addEventListener("click", function() {
+			console.log('clicked listner to refresh button');
+			if (!container.classList.contains("refreshing")) {
+				updateAndRefresh();
+			}
+		});
+		toolbar.appendChild(refreshButton);
+	}
+	makeRefreshButton(toolbar, container);
 
 	/**
 	 * @param {HTMLDivElement} container
 	 */
 	function makeSpinner(container) {
-		const spinner = document.createElement("div");
+		spinner = document.createElement("div");
 		spinner.classList.add("spinner");
 		spinner.innerText = '⟳';
 		container.appendChild(spinner);
 	}
 	makeSpinner(container);
 
+
 	/** Refresh on click
 	 * @param {boolean} retry should we retry image generation or not?
 	 */
 	function refresh(retry) {
-		renderAIArt(slave, imageSize).then((imgElement) => {
-			jQuery(container).empty().append(imgElement);
-			makeSpinner(container);
-		}).catch(() => {
-			if (retry) {
-				updateAndRefresh();
-			}
-		});
+		renderAIArt(slave, imageSize)
+			.then((imgElement) => {
+				container.querySelector('.ai-art-image')?.remove();
+				container.prepend(imgElement); // prepend it before the toolbar and spinner, otherwise you can't see them
+			}).catch(() => {
+				if (retry) {
+					updateAndRefresh();
+				}
+			});
 	}
 
 	function updateAndRefresh() {
@@ -502,20 +573,13 @@ App.Art.aiArtElement = function(slave, imageSize) {
 
 		imageGenerator.updateSlave(slave).then(() => {
 			refresh(false);
-
-			container.classList.remove("refreshing");
 		}).catch(error => {
 			console.error(error);
-
+		}).finally(() => {
 			container.classList.remove("refreshing");
 		});
 	}
 
-	container.addEventListener("click", function() {
-		if (!container.classList.contains("refreshing")) {
-			updateAndRefresh();
-		}
-	});
 
 	if (slave.custom.aiImageId === null) {
 		updateAndRefresh();