diff --git a/src/002-config/mousetrapConfig.js b/src/002-config/mousetrapConfig.js
index 48b236a9b47a11481cba0ff54447ac3ff8ce5df5..da2641fb38a03b0b3aae3041456e9e0b7a941f50 100644
--- a/src/002-config/mousetrapConfig.js
+++ b/src/002-config/mousetrapConfig.js
@@ -294,6 +294,16 @@ App.UI.Hotkeys.add("next-child", {
 		$("#next-child a.macro-link").trigger("click");
 	}, combinations: ["right", "e"], uiName: "Next Child"
 });
+App.UI.Hotkeys.add("Previous Tab", {
+	callback: function() {
+		App.UI.tabBar.openLeftTab();
+	}, combinations: []
+});
+App.UI.Hotkeys.add("Next Tab", {
+	callback: function() {
+		App.UI.tabBar.openRightTab();
+	}, combinations: []
+});
 App.UI.Hotkeys.add("walkpast", {
 	callback: function() {
 		$("#walkpast a.macro-link").trigger("click");
diff --git a/src/gui/multipleInspect.js b/src/gui/multipleInspect.js
index 42329d8fe31105c6fc85710d67b5bda52ac712c6..93f5fb27a05a43789191b743afcd4423c478fde7 100644
--- a/src/gui/multipleInspect.js
+++ b/src/gui/multipleInspect.js
@@ -12,19 +12,19 @@ App.UI.MultipleInspect = (function() {
 		const tabBar = App.UI.DOM.appendNewElement("div", frag, "", "tab-bar");
 
 		for (const slave of slaves) {
-			tabBar.append(App.UI.tabBar.tabButtonDOM(`slave${slave.ID}`, slave.slaveName));
-			frag.append(App.UI.tabBar.makeTabDOM(`slave${slave.ID}`, App.Desc.longSlave(slave, {market: market})));
+			tabBar.append(App.UI.tabBar.tabButton(`slave${slave.ID}`, slave.slaveName));
+			frag.append(App.UI.tabBar.makeTab(`slave${slave.ID}`, App.Desc.longSlave(slave, {market: market})));
 		}
 
 		if (slaves.length > 1 && showFamilyTree) {
-			const button = App.UI.tabBar.tabButtonDOM(`familyTreeTab`, "Family Tree");
+			const button = App.UI.tabBar.tabButton(`familyTreeTab`, "Family Tree");
 			button.addEventListener('click', event => {
 				renderFamilyTree(slaves, slaves[0].ID);
 			});
 			tabBar.append(button);
 			const ftTarget = document.createElement("div");
 			ftTarget.setAttribute("id", "family-tree");
-			frag.append(App.UI.tabBar.makeTabDOM(`familyTreeTab`, ftTarget));
+			frag.append(App.UI.tabBar.makeTab(`familyTreeTab`, ftTarget));
 		}
 
 		App.UI.tabBar.handlePreSelectedTab(`slave${slaves[0].ID}`);
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index 653ccc8655c80dc48d781e041e4b323bcdea4b26..64051f6a7a9583f7cf0ea65b34e4e2e88eb5a3db 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -633,20 +633,20 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show
 	}
 	const tabBar = App.UI.DOM.appendNewElement("div", frag, '', "tab-bar");
 	tabBar.append(
-		App.UI.tabBar.tabButtonDOM('assign', tabCaptions.assign),
-		App.UI.tabBar.tabButtonDOM('remove', tabCaptions.remove),
-		(showTransfersTab ? App.UI.tabBar.tabButtonDOM('transfer', tabCaptions.transfer) : '')
+		App.UI.tabBar.tabButton('assign', tabCaptions.assign),
+		App.UI.tabBar.tabButton('remove', tabCaptions.remove),
+		(showTransfersTab ? App.UI.tabBar.tabButton('transfer', tabCaptions.transfer) : '')
 	);
 
 	const facilitySlaves = [...job.employeesIDs()];
 	if (facilitySlaves.length > 0) {
 		SlaveSort.IDs(facilitySlaves);
-		frag.append(App.UI.tabBar.makeTabDOM("remove", App.UI.SlaveList.render(facilitySlaves, [],
+		frag.append(App.UI.tabBar.makeTab("remove", App.UI.SlaveList.render(facilitySlaves, [],
 			App.UI.SlaveList.SlaveInteract.stdInteract,
 			(slave) => App.UI.DOM.link(`Retrieve ${getPronouns(slave).object} from ${facility.name}`, () => removeJob(slave, job.desc.assignment), [], facilityPassage)
 		)));
 	} else {
-		frag.append(App.UI.tabBar.makeTabDOM("remove", App.UI.DOM.makeElement("em", `${capFirstChar(facility.name)} is empty for the moment`)));
+		frag.append(App.UI.tabBar.makeTab("remove", App.UI.DOM.makeElement("em", `${capFirstChar(facility.name)} is empty for the moment`)));
 	}
 
 	/**
@@ -673,9 +673,9 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show
 		const assignableSlaveIDs = job.desc.partTime ?
 			V.slaves.map(slave => slave.ID) : // all slaves can work here
 			[...App.Entity.facilities.penthouse.employeesIDs()]; // only slaves from the penthouse can be transferred here
-		frag.append(App.UI.tabBar.makeTabDOM("assign", assignableTabContent(assignableSlaveIDs)));
+		frag.append(App.UI.tabBar.makeTab("assign", assignableTabContent(assignableSlaveIDs)));
 	} else {
-		frag.append(App.UI.tabBar.makeTabDOM("assign", App.UI.DOM.makeElement("strong", `${capFirstChar(facility.name)} is full and cannot hold any more slaves`)));
+		frag.append(App.UI.tabBar.makeTab("assign", App.UI.DOM.makeElement("strong", `${capFirstChar(facility.name)} is full and cannot hold any more slaves`)));
 	}
 
 	if (showTransfersTab) {
@@ -687,9 +687,9 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show
 				}
 				return acc;
 			}, []);
-			frag.append(App.UI.tabBar.makeTabDOM("transfer", assignableTabContent(transferableIDs)));
+			frag.append(App.UI.tabBar.makeTab("transfer", assignableTabContent(transferableIDs)));
 		} else {
-			frag.append(App.UI.tabBar.makeTabDOM("transfer", App.UI.DOM.makeElement("strong", `${capFirstChar(facility.name)} is full and cannot hold any more slaves`)));
+			frag.append(App.UI.tabBar.makeTab("transfer", App.UI.DOM.makeElement("strong", `${capFirstChar(facility.name)} is full and cannot hold any more slaves`)));
 		}
 	}
 	App.UI.tabBar.handlePreSelectedTab();
@@ -721,8 +721,8 @@ App.UI.SlaveList.listNGPSlaves = function() {
 	frag.append(this.sortingLinks(thisPassage));
 	const tabBar = App.UI.DOM.appendNewElement("div", frag, '', "tab-bar");
 	tabBar.append(
-		App.UI.tabBar.tabButtonDOM('assign', "Import a slave"),
-		App.UI.tabBar.tabButtonDOM('remove', "Remove from import")
+		App.UI.tabBar.tabButton('assign', "Import a slave"),
+		App.UI.tabBar.tabButton('remove', "Remove from import")
 	);
 
 	let imported = [];
@@ -741,22 +741,22 @@ App.UI.SlaveList.listNGPSlaves = function() {
 
 	if (imported.length > 0) {
 		SlaveSort.IDs(imported);
-		frag.append(App.UI.tabBar.makeTabDOM("remove", App.UI.SlaveList.render(imported, [],
+		frag.append(App.UI.tabBar.makeTab("remove", App.UI.SlaveList.render(imported, [],
 			App.UI.SlaveList.makeNameDecorator(["emphasizedSlave", "pink"]),
 			(s) => App.UI.DOM.passageLink('Remove from import list', thisPassage, () => removeJob(s, Job.IMPORTED))
 		)));
 	} else {
-		frag.append(App.UI.tabBar.makeTabDOM("remove", App.UI.DOM.makeElement('em', "No slaves will go with you to the new game")));
+		frag.append(App.UI.tabBar.makeTab("remove", App.UI.DOM.makeElement('em', "No slaves will go with you to the new game")));
 	}
 
 	if (imported.length < V.slavesToImportMax) {
 		SlaveSort.IDs(nonImported);
-		frag.append(App.UI.tabBar.makeTabDOM("assign", App.UI.SlaveList.render(nonImported, [],
+		frag.append(App.UI.tabBar.makeTab("assign", App.UI.SlaveList.render(nonImported, [],
 			App.UI.SlaveList.makeNameDecorator(["emphasizedSlave", "pink"]),
 			(s) => App.UI.DOM.passageLink('Add to import list', thisPassage, () => assignJob(s, Job.IMPORTED))
 		)));
 	} else {
-		frag.append(App.UI.tabBar.makeTabDOM("assign", App.UI.DOM.makeElement('strong', `Slave import limit reached`)));
+		frag.append(App.UI.tabBar.makeTab("assign", App.UI.DOM.makeElement('strong', `Slave import limit reached`)));
 	}
 
 	App.UI.tabBar.handlePreSelectedTab();
@@ -1055,12 +1055,12 @@ App.UI.SlaveList.penthousePage = function() {
 	if (V.useSlaveSummaryTabs === 0) {
 		const links = [];
 		for (const tab of tabs) {
-			links.push(App.UI.tabBar.tabButtonDOM(tab.tabName, tab.caption, true));
+			links.push(App.UI.tabBar.tabButton(tab.tabName, tab.caption, true));
 		}
 		div.append(App.UI.DOM.arrayToList(links, " | ", " | "));
 	} else {
 		for (const tab of tabs) {
-			const button = App.UI.tabBar.tabButtonDOM(tab.tabName, tab.caption);
+			const button = App.UI.tabBar.tabButton(tab.tabName, tab.caption);
 			if (V.useSlaveSummaryTabs === 2) {
 				button.classList.add("card");
 			}
@@ -1070,7 +1070,7 @@ App.UI.SlaveList.penthousePage = function() {
 	fragment.append(div);
 
 	for (const tab of tabs) {
-		const div = App.UI.tabBar.makeTabDOM(tab.tabName, tab.content);
+		const div = App.UI.tabBar.makeTab(tab.tabName, tab.content);
 		if (V.useSlaveSummaryTabs === 0) {
 			div.classList.add("noFade");
 		} else if (V.useSlaveSummaryTabs === 2) {
diff --git a/src/js/utilsSC.js b/src/js/utilsSC.js
index 1c275870b223d9650a9de67141c4d73e8ccfb2a2..ecf2ec5c071aeb43f860dc4716c63abcee508d4e 100644
--- a/src/js/utilsSC.js
+++ b/src/js/utilsSC.js
@@ -14,7 +14,8 @@ globalThis.html5passage = function(passageFunction) {
 };
 
 /**
- * If you want to include a SugarCube passage in a JS function use this. The result must be printed using the <<print>> macro.
+ * If you want to include a SugarCube passage in a JS function use this. The result must be printed using the <<print>>
+ * macro.
  * @param {string} passageTitle
  * @returns {string}
  */
@@ -118,11 +119,11 @@ App.UI.tabBar = function() {
 	return {
 		openTab: openTab,
 		tabButton: tabButton,
-		tabButtonDOM: tabButtonDOM,
 		makeTab: makeTab,
-		makeTabDOM: makeTabDOM,
 		handlePreSelectedTab: handlePreSelectedTab,
-		tabChoiceVarName: tabChoiceVarName
+		tabChoiceVarName: tabChoiceVarName,
+		openLeftTab: openLeft,
+		openRightTab: openRight
 	};
 
 	function openTab(evt, tabName) {
@@ -140,22 +141,13 @@ App.UI.tabBar = function() {
 		evt.currentTarget.className += " active";
 	}
 
-	/**
-	 * @param {string} name
-	 * @param {string} text
-	 * @returns {string}
-	 */
-	function tabButton(name, text) {
-		return `<button class="tab-links" onclick="App.UI.tabBar.openTab(event, '${name}')" id="tab ${name}">${text}</button>`;
-	}
-
 	/**
 	 * @param {string} name
 	 * @param {string} text
 	 * @param {boolean} [plainLink]
 	 * @returns {HTMLButtonElement|HTMLAnchorElement}
 	 */
-	function tabButtonDOM(name, text, plainLink = false) {
+	function tabButton(name, text, plainLink = false) {
 		if (plainLink) {
 			const link = document.createElement("a");
 			link.classList.add("tab-links", "pure");
@@ -177,21 +169,12 @@ App.UI.tabBar = function() {
 		}
 	}
 
-	/**
-	 * @param {string} name
-	 * @param {string} content
-	 * @returns {string}
-	 */
-	function makeTab(name, content) {
-		return `<div id="${name}" class="tab-content"><div class="content">${content}</div></div>`;
-	}
-
 	/**
 	 * @param {string} name
 	 * @param {Node} content
 	 * @returns {HTMLDivElement}
 	 */
-	function makeTabDOM(name, content) {
+	function makeTab(name, content) {
 		const outerDiv = document.createElement("div");
 		outerDiv.id = name;
 		outerDiv.classList.add("tab-content");
@@ -227,6 +210,32 @@ App.UI.tabBar = function() {
 	function tabChoiceVarName() {
 		return passage().trim().replace(/ |'/g, '');
 	}
+
+	function openLeft() {
+		const tabLinks = /** @type {HTMLCollection<HTMLButtonElement>} */ document.getElementsByClassName("tab-links");
+		const index = currentIndex(tabLinks);
+		if (index - 1 >= 0) {
+			tabLinks[index - 1].click();
+		}
+	}
+
+	function openRight() {
+		const tabLinks = /** @type {HTMLCollection<HTMLButtonElement>} */ document.getElementsByClassName("tab-links");
+		const index = currentIndex(tabLinks);
+		if (index > -1 && index + 1 < tabLinks.length) {
+			tabLinks[index + 1].click();
+		}
+	}
+
+	function currentIndex(collection) {
+		// get current tab button
+		for (let i = 0; i < collection.length; i++) {
+			if (collection[i].classList.contains("active")) {
+				return i;
+			}
+		}
+		return -1;
+	}
 }();
 
 /**