diff --git a/src/004-base/organFarmBase.js b/src/004-base/organFarmBase.js
index 11fd5eb80313f09d911d47f8f4eb7d04f1d9c0f2..b6e2c6a7e2627f9f63c7158e6ca6686452bc2ccf 100644
--- a/src/004-base/organFarmBase.js
+++ b/src/004-base/organFarmBase.js
@@ -8,8 +8,10 @@ App.Medicine.OrganFarm.Organ = class {
 	 * @param {function(App.Entity.SlaveState):boolean} canGrow
 	 * @param {string[]} dependencies - organs that are implanted first if possible, use type of other organs as values
 	 * @param {App.Medicine.OrganFarm.OrganImplantAction[]} actions
+	 * @param {boolean} [displayMultipleActions=false] allow multiple implant links to be displayed
 	 */
-	constructor({type: type, name, tooltip= "", cost, time, canGrow = () => true, dependencies = [], actions= []} = {}) {
+	constructor({type, name, tooltip = "", cost, time, canGrow = () => true, dependencies = [],
+		displayMultipleActions = false, actions = []} = {}) {
 		this.type = type;
 		this.name = name;
 		this.tooltip = tooltip;
@@ -19,6 +21,7 @@ App.Medicine.OrganFarm.Organ = class {
 		this.canGrow = canGrow;
 		/** @type {string[]} */
 		this.dependencies = dependencies;
+		this.displayMultipleActions = displayMultipleActions;
 		/** @type {App.Medicine.OrganFarm.OrganImplantAction[]} */
 		this.implantActions = actions;
 
diff --git a/src/gui/css/mainStyleSheet.css b/src/gui/css/mainStyleSheet.css
index 47af08439aa425221b30d19aad0d3ea1023f235f..99a23af72c15df74833beeb920c99ff775bd56d1 100644
--- a/src/gui/css/mainStyleSheet.css
+++ b/src/gui/css/mainStyleSheet.css
@@ -409,3 +409,8 @@ div.center {
 div.flex-container {
 	display: flex;
 }
+
+/* TODO unify tooltip systems */
+.hasTooltip {
+	text-decoration: underline;
+}
\ No newline at end of file
diff --git a/src/npc/surgery/organFarm.js b/src/npc/surgery/organFarm.js
index a1aafe6b95602ff4b32fc893d9000de38c122f55..ec09f300f84a86d33d04f80ef6e4c208088678df 100644
--- a/src/npc/surgery/organFarm.js
+++ b/src/npc/surgery/organFarm.js
@@ -85,49 +85,57 @@ App.Medicine.OrganFarm.growIncubatorOrgan = function(slave, organType) {
 
 /**
  * @param {App.Entity.SlaveState} slave
- * @returns {string}
+ * @returns {DocumentFragment}
  */
 App.Medicine.OrganFarm.implantActions = function(slave) {
 	let slaveOrgans = V.completedOrgans.filter(o => o.ID === slave.ID);
-	if (slaveOrgans.length === 0) { return ""; }
+	if (slaveOrgans.length === 0) { return null; }
 
 	const F = App.Medicine.OrganFarm;
-	let r = "";
+	const grid = document.createElement("div");
+	grid.classList.add("grid-2columns-auto");
 
 	for (const organ of slaveOrgans) {
-		r += `<div>${F.Organs[organ.type].name}:</div><div>`;
+		App.UI.DOM.appendNewElement("div", grid, F.Organs[organ.type].name);
 
-		let anyAction = false;
-		let lines = [];
+		let links = [];
 		for (let i = 0; i < F.Organs[organ.type].implantActions.length; i++) {
 			const action = F.Organs[organ.type].implantActions[i];
 			if (action.canImplant(slave)) {
-				const implantLink = App.UI.link(action.name, App.Medicine.OrganFarm.implant, [slave, organ.type, i], "Surgery Degradation");
-				lines.push(`<span class="detail">${action.tooltip === "" ? "" : `${capFirstChar(action.tooltip)}: `}</span>${implantLink}`);
-				anyAction = true;
-				break; // there can only be one implant action
+				const link = App.UI.DOM.link(action.name, App.Medicine.OrganFarm.implant, [slave, organ.type, i], "Surgery Degradation");
+				const tooltip = action.tooltip === "" ? "" : `${capFirstChar(action.tooltip)}.`;
+				if (tooltip !== "") {
+					link.title = tooltip;
+					link.classList.add("hasTooltip");
+				}
+				links.push(link);
+				if (!F.Organs[organ.type].displayMultipleActions) {
+					break; // there can only be one implant action
+				}
 			} else {
 				const error = action.implantError(slave);
 				if (error !== "") {
-					lines.push(`ERROR: ${error} `);
+					const disabledLink = document.createElement("span");
+					disabledLink.append(action.name);
+					disabledLink.title = (error);
+					disabledLink.classList.add("hasTooltip");
+					links.push(disabledLink);
 				}
 			}
 		}
 
-		// each error on a new line
-		for (let i = 0; i < lines.length - 1; i++) {
-			r += `<div>${lines[i]}</div>`;
+		// all links in a row
+		const div = document.createElement("div");
+		for (let i = 0; i < links.length; i++) {
+			div.append(links[i], " | ");
 		}
 
 		// last error or implant action has "Discard" after them.
-		r += `<div>${lines[lines.length - 1]}`;
-		if (anyAction) {
-			r += " | ";
-		}
-		r += `${App.UI.link("Discard", App.Medicine.OrganFarm.removeOrgan, [slave, organ.type], "Remote Surgery")}</div></div>`;
+		div.append(App.UI.DOM.link("Discard", App.Medicine.OrganFarm.removeOrgan, [slave, organ.type], "Remote Surgery"));
+		grid.append(div);
 	}
 
-	return `The fabricator has completed ${slaveOrgans.length} organ(s):<div class="grid-2columns-auto">${r}</div>`;
+	return App.UI.DOM.combineNodes(`The fabricator has completed ${slaveOrgans.length} organ(s):`, grid);
 };
 
 /**
@@ -194,30 +202,34 @@ App.Medicine.OrganFarm.getSortedOrgans = function(slave) {
  * Returns the full organ farm menu, hiding empty parts
  *
  * @param {App.Entity.SlaveState} slave
- * @returns {string}
+ * @returns {DocumentFragment}
  */
 App.Medicine.OrganFarm.fullMenu = function(slave) {
-	if (V.organFarmUpgrade >= 1 && slave.indentureRestrictions < 2) {
-		let r = "";
-
-		let actions = App.Medicine.OrganFarm.growActions(slave);
-		if (actions !== "") {
-			r += `<h3>Grow new organs</h3><div class="indent">${actions}</div>`;
-		}
+	const fragment = document.createDocumentFragment();
+	if (!(V.organFarmUpgrade >= 1 && slave.indentureRestrictions < 2)) {
+		return fragment;
+	}
 
-		actions = App.Medicine.OrganFarm.implantActions(slave);
-		if (actions !== "") {
-			r += `<h3>Implant organs</h3><div class="indent">${actions}</div>`;
-		}
+	let actions = App.Medicine.OrganFarm.growActions(slave);
+	let anyAction = false;
+	if (actions !== "") {
+		$(fragment).append(Wikifier.wikifyEval(`<h3>Grow new organs</h3><div class="indent">${actions}</div>`));
+		anyAction = true;
+	}
 
-		if (r === "") {
-			return "";
-		}
+	actions = App.Medicine.OrganFarm.implantActions(slave);
+	if (actions !== null) {
+		App.UI.DOM.appendNewElement("h3", fragment, "Implant Organs");
+		App.UI.DOM.appendNewElement("div", fragment, actions, "indent");
+		anyAction = true;
+	}
 
-		return `<h2>Organ Farm</h2>${r}`;
-	} else {
-		return "";
+	if (!anyAction) {
+		return fragment;
 	}
+
+	fragment.prepend(App.UI.DOM.makeElement("h2", "Organ Farm"));
+	return fragment;
 };
 
 App.Medicine.OrganFarm.currentlyGrowing = function() {
diff --git a/src/npc/surgery/organs.js b/src/npc/surgery/organs.js
index 4861d11cc80f5dc7ed0214eb84de400eecf4acb7..8401afec4f33f5c39ccc3ed0cab2cf7ec2ea634b 100644
--- a/src/npc/surgery/organs.js
+++ b/src/npc/surgery/organs.js
@@ -387,7 +387,7 @@ App.Medicine.OrganFarm.init = function() {
 	});
 
 	new App.Medicine.OrganFarm.Organ({
-		type: "hair", name: "Hair Follicles", cost: 500, time: 2,
+		type: "hair", name: "Hair Follicles", cost: 500, time: 2, displayMultipleActions: true,
 		actions: [
 			new App.Medicine.OrganFarm.OrganImplantAction({
 				name: "Scalp", healthImpact: 10, surgeryType: "restoreHairHead",
@@ -424,7 +424,7 @@ App.Medicine.OrganFarm.init = function() {
 				name: "Brow", healthImpact: 5,
 				surgeryType: "restoreHairBrow", autoImplant: false,
 				canImplant: s => (s.eyebrowHStyle === "bald"),
-				implantError: () => "This slave already has eyebrows.",
+				implantError: () => "",
 				implant: s => {
 					s.eyebrowHStyle = "natural";
 					s.eyebrowFullness = "natural";
@@ -435,7 +435,7 @@ App.Medicine.OrganFarm.init = function() {
 				name: "Axillary", healthImpact: 5,
 				surgeryType: "restoreHairPits", autoImplant: false,
 				canImplant: s => (s.underArmHStyle === "bald" || s.underArmHStyle === "hairless"),
-				implantError: () => "This slave already has underarm hair.",
+				implantError: () => "",
 				implant: s => {
 					s.underArmHStyle = "bushy";
 					s.underArmHColor = s.origHColor;
@@ -445,7 +445,7 @@ App.Medicine.OrganFarm.init = function() {
 				name: "Pubic", healthImpact: 5,
 				surgeryType: "restoreHairPubes", autoImplant: false,
 				canImplant: s => (s.pubicHStyle === "bald" || s.pubicHStyle === "hairless"),
-				implantError: () => "This slave already has pubic hair.",
+				implantError: () => "",
 				implant: s => {
 					s.pubicHStyle = "very bushy";
 					s.pubicHColor = s.origHColor;
diff --git a/src/npc/surgery/reproductiveOrgans.js b/src/npc/surgery/reproductiveOrgans.js
index d0b4ae72f263adeceb761699ea38481cc2bdc035..bdf1598930b4e38f4aec53ed754ee5b179e9f2f3 100644
--- a/src/npc/surgery/reproductiveOrgans.js
+++ b/src/npc/surgery/reproductiveOrgans.js
@@ -70,7 +70,7 @@ App.Medicine.OrganFarm.Testicles = class extends App.Medicine.OrganFarm.Organ {
 				}),
 				new App.Medicine.OrganFarm.TesticlesImplantAction({
 					name: "Implant",
-					tooltip: "you can forgo standard procedure and implant testicles directly into $his abdomen",
+					tooltip: "you can forgo standard procedure and implant testicles directly into their abdomen",
 					ballType: ballType, animal: animal, surgeryType: "addTesticles", autoImplant: false,
 					canImplant: slave => (slave.dick === 0 && slave.balls <= 0),
 					implantError: slave => ((slave.balls > 0) ? "This slave already has testicles." : ""),
diff --git a/src/uncategorized/remoteSurgery.tw b/src/uncategorized/remoteSurgery.tw
index 44958ba77558e1cfdc28bc4f8c025719682cda91..66cece0c3f6c9af68874cd534ce07a8a6b3dcf2c 100644
--- a/src/uncategorized/remoteSurgery.tw
+++ b/src/uncategorized/remoteSurgery.tw
@@ -2084,7 +2084,7 @@
 			<</if>>
 		</div>
 
-		<<print App.Medicine.OrganFarm.fullMenu(getSlave($AS))>>
+		<<includeDOM App.Medicine.OrganFarm.fullMenu(getSlave($AS))>>
 
 		<<if $geneticMappingUpgrade >= 1>>
 			<h3>Retro-virus treatments:</h3>