diff --git a/src/interaction/slaveInteract.js b/src/interaction/slaveInteract.js
index 0960e29f64c2bc081ac856f1c9a48c2689a49662..45f028983e4e7cc1929d86ba81b0401e5df71451 100644
--- a/src/interaction/slaveInteract.js
+++ b/src/interaction/slaveInteract.js
@@ -1,4 +1,9 @@
 /* eslint-disable no-unused-vars */ // TODO: remove after testing
+
+/** Find the previous and next slaves' IDs based on the current sort order
+ * @param {App.Entity.SlaveState} slave
+ * @returns {[number, number]} - previous and next slave ID
+ */
 App.UI.SlaveInteract.placeInLine = function(slave) {
 	const useSlave = assignmentVisible(slave) ? ((s) => assignmentVisible(s)) : ((s) => slave.assignment === s.assignment);
 	const slaveList = V.slaves.filter(useSlave);
@@ -97,6 +102,7 @@ App.UI.SlaveInteract.modify = function(slave) {
 
 /**
  * @param {App.Entity.SlaveState} slave
+ * @returns {HTMLElement}
  */
 App.UI.SlaveInteract.fucktoyPref = function(slave) {
 	const {his} = getPronouns(slave);
@@ -148,7 +154,7 @@ App.UI.SlaveInteract.fucktoyPref = function(slave) {
 
 		// add a note node if required
 		if (linkDesc.note) {
-			App.UI.DOM.appendNewElement("span", link, `${linkDesc.note} `, "note");
+			App.UI.DOM.appendNewElement("span", link, linkDesc.note, "note");
 		}
 		return link;
 	}
@@ -247,7 +253,7 @@ App.UI.SlaveInteract.work = function(slave) {
 			// CAN BE REASSIGNED
 			span.classList.remove("note");
 			span.id = "assignmentLinks";
-			span.appendChild(App.UI.SlaveInteract.assignmentBlock("assignmentLinks", slave));
+			span.appendChild(App.UI.SlaveInteract.assignmentBlock(slave));
 
 			if ((V.brothel + V.club + V.dairy + V.farmyard + V.servantsQuarters + V.masterSuite + V.spa + V.nursery + V.clinic + V.schoolroom + V.cellblock + V.arcade + V.HGSuite) > 0) {
 				span.append(`Transfer to: `);
@@ -284,10 +290,7 @@ App.UI.SlaveInteract.work = function(slave) {
 		div.append(span);
 		div.append(`. `);
 
-		span = document.createElement('span');
-		span.className = "note";
-		span.textContent = `This is the highest class they are allowed to service, when eligible `;
-		div.append(span);
+		div.append(App.UI.DOM.makeElement('span', `This is the highest class they are allowed to service, when eligible `, 'note'));
 
 		appendLink(`Auto`, 0, true);
 		appendLink(`Lower Class`, 1, true);
@@ -315,7 +318,7 @@ App.UI.SlaveInteract.work = function(slave) {
 
 		// add a note node if required
 		if (linkDesc.note) {
-			App.UI.DOM.appendNewElement("span", link, `${linkDesc.note} `, "note");
+			App.UI.DOM.appendNewElement("span", link, linkDesc.note, "note");
 		}
 		return link;
 	}
@@ -324,10 +327,9 @@ App.UI.SlaveInteract.work = function(slave) {
 };
 
 /**
- * @param {string} blockId
  * @param {App.Entity.SlaveState} slave
  */
-App.UI.SlaveInteract.assignmentBlock = function(blockId, slave) {
+App.UI.SlaveInteract.assignmentBlock = function(slave) {
 	let el = document.createElement('div');
 	let title = document.createElement('div');
 	let separator = document.createTextNode(` | `);
@@ -395,17 +397,6 @@ App.UI.SlaveInteract.assignmentBlock = function(blockId, slave) {
 App.UI.SlaveInteract.drugs = function(slave) {
 	let el = document.createElement('div');
 
-	const {
-		// eslint-disable-next-line no-unused-vars
-		he,
-		him,
-		his,
-		hers,
-		himself,
-		boy,
-		He,
-		His
-	} = getPronouns(slave);
 	const drugLevelOptions = [];
 	const lips = [];
 	const breasts = [];
@@ -637,87 +628,16 @@ App.UI.SlaveInteract.drugs = function(slave) {
 	title.appendChild(App.UI.SlaveInteract.generateRows(drugLevelOptions, slave));
 	el.append(title);
 
-	let links;
-	if (lips.length) {
-		links = document.createElement('div');
-		links.append(`Lips: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(lips, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (breasts.length) {
-		links = document.createElement('div');
-		links.append(`Breasts: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(breasts, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (nipples.length) {
-		links = document.createElement('div');
-		links.append(`Nipples: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(nipples, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (butt.length) {
-		links = document.createElement('div');
-		links.append(`Butt: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(butt, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (dick.length) {
-		links = document.createElement('div');
-		links.append(`Dick: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(dick, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (balls.length) {
-		links = document.createElement('div');
-		links.append(`Balls: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(balls, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (fertility.length) {
-		links = document.createElement('div');
-		links.append(`Fertility: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(fertility, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (hormones.length) {
-		links = document.createElement('div');
-		links.append(`Hormones: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(hormones, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (psych.length) {
-		links = document.createElement('div');
-		links.append(`Psych: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(psych, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (misc.length) {
-		links = document.createElement('div');
-		links.append(`Misc: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(misc, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Lips", lips, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Breasts", breasts, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Nipples", nipples, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Butt", butt, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Dick", dick, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Balls", balls, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Fertility", fertility, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Hormones", hormones, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Psych", psych, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Misc", misc, slave);
 
 	return jQuery('#drugs').empty().append(el);
 };
@@ -872,46 +792,11 @@ App.UI.SlaveInteract.diet = function(slave) {
 		}
 	}
 
-	let links;
-	if (health.length) {
-		links = document.createElement('div');
-		links.append(`Health: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(health, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (weight.length) {
-		links = document.createElement('div');
-		links.append(`Weight: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(weight, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (muscle.length) {
-		links = document.createElement('div');
-		links.append(`Muscle: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(muscle, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (production.length) {
-		links = document.createElement('div');
-		links.append(`Production: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(production, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (hormone.length) {
-		links = document.createElement('div');
-		links.append(`Hormone: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(hormone, slave));
-		links.className = "choices";
-		el.append(links);
-	}
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Health", health, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Weight", weight, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Muscle", muscle, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Production", production, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Hormone", hormone, slave);
 
 	return jQuery('#diet').empty().append(el);
 };
@@ -934,7 +819,6 @@ App.UI.SlaveInteract.dietBase = function(slave) {
 		milk.push({text: `Milk`, disabled: `Diet is based entirely on cum`});
 	}
 
-
 	// Cum
 	if (slave.dietMilk < 2) {
 		cum.push({text: `Cum added`, updateSlave: {dietCum: 1}});
@@ -969,21 +853,8 @@ App.UI.SlaveInteract.dietBase = function(slave) {
 	title.append(choice);
 	el.append(title);
 
-	let links;
-	if (milk.length) {
-		links = document.createElement('div');
-		links.append(`Milk: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(milk, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-	if (cum.length) {
-		links = document.createElement('div');
-		links.append(`Cum: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(cum, slave));
-		links.className = "choices";
-		el.append(links);
-	}
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Milk", milk, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Cum", cum, slave);
 
 	return jQuery('#dietBase').empty().append(el);
 };
@@ -1016,7 +887,6 @@ App.UI.SlaveInteract.snacks = function(slave) {
 		title.append(choice);
 		el.append(title);
 
-
 		options.push({text: `No access`, updateSlave: {onDiet: 1}});
 		options.push({text: `Full access`, updateSlave: {onDiet: 0}});
 
@@ -1421,10 +1291,7 @@ App.UI.SlaveInteract.useSlaveDisplay = function(slave) {
 
 				// add a note node if required
 				if (sexArray[i].note) {
-					let note = document.createElement('span');
-					note.textContent = `${sexArray[i].note} `;
-					note.className = "note";
-					link.appendChild(note);
+					link.appendChild(App.UI.DOM.makeElement('span', sexArray[i].note, 'note'));
 				}
 			}
 			row.appendChild(link);
@@ -1503,13 +1370,13 @@ App.UI.SlaveInteract.bloating = function(slave) {
 			let link = App.UI.DOM.link(
 				`Let ${him} deflate`,
 				() => {
-					slave.inflation = 0,
-						slave.inflationType = "none",
-						slave.inflationMethod = 0,
-						slave.cumSource = 0,
-						slave.milkSource = 0,
-						SetBellySize(slave),
-						App.UI.SlaveInteract.refreshAll(slave);
+					slave.inflation = 0;
+					slave.inflationType = "none";
+					slave.inflationMethod = 0;
+					slave.cumSource = 0;
+					slave.milkSource = 0;
+					SetBellySize(slave);
+					App.UI.SlaveInteract.refreshAll(slave);
 				},
 			);
 			bloating.append(link);
@@ -1517,11 +1384,11 @@ App.UI.SlaveInteract.bloating = function(slave) {
 			let link = App.UI.DOM.link(
 				`Let ${him} deflate`,
 				() => {
-					slave.inflation = 0,
-						slave.inflationType = "none",
-						slave.inflationMethod = 0,
-						SetBellySize(slave),
-						App.UI.SlaveInteract.refreshAll(slave);
+					slave.inflation = 0;
+					slave.inflationType = "none";
+					slave.inflationMethod = 0;
+					SetBellySize(slave);
+					App.UI.SlaveInteract.refreshAll(slave);
 				},
 			);
 			bloating.append(link);
@@ -1583,8 +1450,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.append(App.UI.DOM.link(
 					`Turn on implant`,
 					() => {
-						slave.broodmotherOnHold = 0,
-							slave.broodmotherCountDown = 0;
+						slave.broodmotherOnHold = 0;
+						slave.broodmotherCountDown = 0;
 					},
 					[],
 					"Slave Interact"
@@ -1614,8 +1481,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Use contraceptives`,
 					() => {
-						slave.preg = -1,
-							App.UI.SlaveInteract.refreshAll(slave);
+						slave.preg = -1;
+						App.UI.SlaveInteract.refreshAll(slave);
 					},
 				));
 				fertilityblock.append(link);
@@ -1623,8 +1490,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Let ${him} get pregnant`,
 					() => {
-						slave.preg = 0,
-							App.UI.SlaveInteract.refreshAll(slave);
+						slave.preg = 0;
+						App.UI.SlaveInteract.refreshAll(slave);
 					},
 				));
 				fertilityblock.append(link);
@@ -1634,9 +1501,9 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Induce labor`,
 					() => {
-						slave.labor = 1,
-							slave.induce = 1,
-							V.birthee = 1;
+						slave.labor = 1;
+						slave.induce = 1;
+						V.birthee = 1;
 					},
 					[],
 					"Slave Interact"
@@ -1649,8 +1516,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 					link.appendChild(App.UI.DOM.link(
 						`Turn off implant`,
 						() => {
-							slave.broodmotherOnHold = 1,
-								slave.broodmotherCountDown = 38 - WombMinPreg(slave);
+							slave.broodmotherOnHold = 1;
+							slave.broodmotherCountDown = 38 - WombMinPreg(slave);
 						},
 					));
 					fertilityblock.append(link);
@@ -1666,8 +1533,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Give ${him} a cesarean section`,
 					() => {
-						slave.broodmotherOnHold = 0,
-							slave.broodmotherCountDown = 0;
+						slave.broodmotherOnHold = 0;
+						slave.broodmotherCountDown = 0;
 					},
 					[],
 					"csec"
@@ -1679,8 +1546,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Abort ${his} pregnancy`,
 					() => {
-						slave.broodmotherOnHold = 0,
-							slave.broodmotherCountDown = 0;
+						slave.broodmotherOnHold = 0;
+						slave.broodmotherCountDown = 0;
 					},
 					[],
 					"Abort"
@@ -1728,16 +1595,16 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Normal Birth`,
 					() => {
-						slave.pregControl = "none",
-							App.UI.SlaveInteract.fertility(slave);
+						slave.pregControl = "none";
+						App.UI.SlaveInteract.fertility(slave);
 					},
 				));
 			} else {
 				link.appendChild(App.UI.DOM.link(
 					`Suppress Labor`,
 					() => {
-						slave.pregControl = "labor suppressors",
-							App.UI.SlaveInteract.fertility(slave);
+						slave.pregControl = "labor suppressors";
+						App.UI.SlaveInteract.fertility(slave);
 					},
 				));
 			}
@@ -1746,8 +1613,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Normal Gestation`,
 					() => {
-						slave.pregControl = "none",
-							App.UI.SlaveInteract.fertility(slave);
+						slave.pregControl = "none";
+						App.UI.SlaveInteract.fertility(slave);
 					},
 				));
 			}
@@ -1756,8 +1623,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Slow Gestation`,
 					() => {
-						slave.pregControl = "slow gestation",
-							App.UI.SlaveInteract.fertility(slave);
+						slave.pregControl = "slow gestation";
+						App.UI.SlaveInteract.fertility(slave);
 					},
 				));
 			}
@@ -1766,8 +1633,8 @@ App.UI.SlaveInteract.fertility = function(slave) {
 				link.appendChild(App.UI.DOM.link(
 					`Fast Gestation`,
 					() => {
-						slave.pregControl = "speed up",
-							App.UI.SlaveInteract.fertility(slave);
+						slave.pregControl = "speed up";
+						App.UI.SlaveInteract.fertility(slave);
 					},
 				));
 			}
@@ -2228,7 +2095,6 @@ App.UI.SlaveInteract.smartSettings = function(slave) {
 	}
 
 	let title = document.createElement('div');
-	title.textContent = ``;
 	if (slave.clitPiercing === 3) {
 		if (slave.dick < 1) {
 			title.textContent = `${His} smart clit piercing `;
@@ -2256,38 +2122,10 @@ App.UI.SlaveInteract.smartSettings = function(slave) {
 	title.append(selected);
 	el.append(title);
 
-	let links;
-	if (level.length) {
-		links = document.createElement('div');
-		links.append(`Level: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(level, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (bodyPart.length) {
-		links = document.createElement('div');
-		links.append(`Body part: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(bodyPart, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (BDSM.length) {
-		links = document.createElement('div');
-		links.append(`BDSM: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(BDSM, slave));
-		links.className = "choices";
-		el.append(links);
-	}
-
-	if (gender.length) {
-		links = document.createElement('div');
-		links.append(`Gender: `);
-		links.appendChild(App.UI.SlaveInteract.generateRows(gender, slave));
-		links.className = "choices";
-		el.append(links);
-	}
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Level", level, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Body part", bodyPart, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "BDSM", BDSM, slave);
+	App.UI.SlaveInteract.appendLabeledChoiceRow(el, "Gender", gender, slave);
 
 	return jQuery('#smartSettings').empty().append(el);
 };
@@ -2377,9 +2215,7 @@ App.UI.SlaveInteract.custom = (function() {
 		let intro = document.createElement('p');
 		intro.className = "scene-intro";
 		intro.append(`You may enter custom descriptors for your slave's hair color, hair style, tattoos, or anything else here. After typing, press `);
-		let introPiece = document.createElement('kbd');
-		introPiece.textContent = `enter`;
-		intro.appendChild(introPiece);
+		intro.appendChild(App.UI.DOM.makeElement("kbd", "enter"));
 		intro.append(` to commit your change. These custom descriptors will appear in descriptions of your slave, but will have no gameplay effect. Changing them is free.`);
 		return intro;
 	}
@@ -2400,9 +2236,9 @@ App.UI.SlaveInteract.custom = (function() {
 		label = document.createElement('div');
 		if (slave.devotion >= -50) {
 			if (slave.custom.title !== "") {
-				label.textContent = `You have instructed ${him} to always refer to you as ${slave.custom.title}, which, should ${he} lisp, comes out as ${slave.custom.titleLisp}. `;
+				label.textContent = `You have instructed ${him} to always refer to you as ${slave.custom.title}, which, should ${he} lisp, comes out as ${slave.custom.titleLisp}.`;
 			} else {
-				label.textContent = `You expect ${him} to refer to you as all your other slaves do. `;
+				label.textContent = `You expect ${him} to refer to you as all your other slaves do.`;
 			}
 			result = document.createElement('div');
 			result.id = "result";
@@ -2424,11 +2260,11 @@ App.UI.SlaveInteract.custom = (function() {
 				textbox = App.UI.DOM.makeTextBox(
 					"",
 					v => {
-						slave.custom.title = v,
-							jQuery('#result').empty().append(
-								document.createTextNode(`${He}'ll try ${his} best to call you ${slave.custom.title}. `)
-							),
-							slave.custom.titleLisp = lispReplace(slave.custom.title);
+						slave.custom.title = v;
+						jQuery('#result').empty().append(
+							document.createTextNode(`${He}'ll try ${his} best to call you ${slave.custom.title}.`)
+						);
+						slave.custom.titleLisp = lispReplace(slave.custom.title);
 					});
 				shownTextBox.appendChild(textbox);
 			} else {
@@ -2436,11 +2272,11 @@ App.UI.SlaveInteract.custom = (function() {
 				textbox = App.UI.DOM.makeTextBox(
 					slave.custom.title,
 					v => {
-						slave.custom.title = v,
-							jQuery('#result').empty().append(
-								document.createTextNode(`${He}'ll try ${his} best to call you ${slave.custom.title}. `)
-							),
-							slave.custom.titleLisp = lispReplace(slave.custom.title);
+						slave.custom.title = v;
+						jQuery('#result').empty().append(
+							document.createTextNode(`${He}'ll try ${his} best to call you ${slave.custom.title}.`)
+						);
+						slave.custom.titleLisp = lispReplace(slave.custom.title);
 					});
 				result.appendChild(textbox);
 				result.appendChild(
@@ -2449,8 +2285,8 @@ App.UI.SlaveInteract.custom = (function() {
 						() => {
 							jQuery('#result').empty().append(
 								document.createTextNode(`${He} will no longer refer to you with a special title.`)
-							),
-								slave.custom.title = "";
+							);
+							slave.custom.title = "";
 							slave.custom.titleLisp = "";
 						}
 					)
@@ -2493,7 +2329,7 @@ App.UI.SlaveInteract.custom = (function() {
 			slaveFullNameNode.appendChild(slaveName());
 			slaveFullNameNode.appendChild(slaveSurname());
 		} else {
-			slaveFullNameNode.textContent = `You must break ${his} will further before you can successfully force a new name on ${him}. `;
+			slaveFullNameNode.textContent = `You must break ${his} will further before you can successfully force a new name on ${him}.`;
 			slaveFullNameNode.className = "note";
 		}
 
@@ -2743,8 +2579,8 @@ App.UI.SlaveInteract.custom = (function() {
 			let textbox = App.UI.DOM.makeTextBox(
 				slave.hStyle,
 				v => {
-					slave.hStyle = v,
-						App.UI.SlaveInteract.custom(slave);
+					slave.hStyle = v;
+					App.UI.SlaveInteract.custom(slave);
 				});
 			label.appendChild(textbox);
 
@@ -2765,10 +2601,7 @@ App.UI.SlaveInteract.custom = (function() {
 
 			let choices = document.createElement('div');
 			choices.className = "choices";
-			let note = document.createElement('span');
-			note.className = "note";
-			note.textContent = ` For best results, use a short, uncapitalized and unpunctuated description; for example: 'back in a ponytail'`;
-			choices.appendChild(note);
+			choices.appendChild(App.UI.DOM.makeElement('span', ` For best results, use a short, uncapitalized and unpunctuated description; for example: 'back in a ponytail'`, 'note'));
 			hairStyleNode.appendChild(choices);
 			return hairStyleNode;
 		}
@@ -2781,8 +2614,8 @@ App.UI.SlaveInteract.custom = (function() {
 			let textbox = App.UI.DOM.makeTextBox(
 				slave.hColor,
 				v => {
-					slave.hColor = v,
-						App.UI.SlaveInteract.custom(slave);
+					slave.hColor = v;
+					App.UI.SlaveInteract.custom(slave);
 				});
 			label.appendChild(textbox);
 			label.append(` "${His} hair is ${slave.hColor}."`);
@@ -2790,10 +2623,7 @@ App.UI.SlaveInteract.custom = (function() {
 
 			let choices = document.createElement('div');
 			choices.className = "choices";
-			let note = document.createElement('span');
-			note.className = "note";
-			note.textContent = ` For best results, use a short, uncapitalized and unpunctuated description; for example: 'black with purple highlights'`;
-			choices.appendChild(note);
+			choices.appendChild(App.UI.DOM.makeElement('span', ` For best results, use a short, uncapitalized and unpunctuated description; for example: 'black with purple highlights'`, 'note'));
 			hairStyleNode.appendChild(choices);
 			return hairStyleNode;
 		}
@@ -2834,8 +2664,8 @@ App.UI.SlaveInteract.custom = (function() {
 			textbox = App.UI.DOM.makeTextBox(
 				slave.eye.left.iris,
 				v => {
-					slave.eye.left.iris = v,
-						App.UI.SlaveInteract.custom(slave);
+					slave.eye.left.iris = v;
+					App.UI.SlaveInteract.custom(slave);
 				});
 			eye.appendChild(textbox);
 			choices.appendChild(eye);
@@ -2846,16 +2676,13 @@ App.UI.SlaveInteract.custom = (function() {
 			textbox = App.UI.DOM.makeTextBox(
 				slave.eye.right.iris,
 				v => {
-					slave.eye.right.iris = v,
-						App.UI.SlaveInteract.custom(slave);
+					slave.eye.right.iris = v;
+					App.UI.SlaveInteract.custom(slave);
 				});
 			eye.appendChild(textbox);
 			choices.appendChild(eye);
 		}
-		let note = document.createElement('span');
-		note.className = "note";
-		note.textContent = `For best results, use a short, uncapitalized and unpunctuated description; for example: 'blue'`;
-		choices.appendChild(note);
+		choices.appendChild(App.UI.DOM.makeElement('span', `For best results, use a short, uncapitalized and unpunctuated description; for example: 'blue'`, 'note'));
 		eyeColorNode.appendChild(choices);
 		return eyeColorNode;
 	}
@@ -2877,17 +2704,13 @@ App.UI.SlaveInteract.custom = (function() {
 		el.appendChild(App.UI.DOM.makeTextBox(
 			slave.custom.tattoo,
 			v => {
-				slave.custom.tattoo = v,
-					App.UI.SlaveInteract.custom(slave);
+				slave.custom.tattoo = v;
+				App.UI.SlaveInteract.custom(slave);
 			}));
 
 		let choices = document.createElement('div');
 		choices.className = "choices";
-
-		let note = document.createElement('span');
-		note.className = "note";
-		note.textContent = `For best results, use complete sentences; for example: '${He} has blue stars tattooed along ${his} cheekbones.'`;
-		choices.appendChild(note);
+		choices.appendChild(App.UI.DOM.makeElement('span', `For best results, use complete sentences; for example: '${He} has blue stars tattooed along ${his} cheekbones.'`, 'note'));
 		el.appendChild(choices);
 
 		return el;
@@ -2911,17 +2734,13 @@ App.UI.SlaveInteract.custom = (function() {
 		el.appendChild(App.UI.DOM.makeTextBox(
 			slave.origin,
 			v => {
-				slave.origin = v,
-					App.UI.SlaveInteract.custom(slave);
+				slave.origin = v;
+				App.UI.SlaveInteract.custom(slave);
 			}));
 
 		let choices = document.createElement('div');
 		choices.className = "choices";
-
-		let note = document.createElement('span');
-		note.className = "note";
-		note.textContent = ` For best results, use complete, capitalized and punctuated sentences; for example: '${He} followed you home from the pet store.'`;
-		choices.appendChild(note);
+		choices.appendChild(App.UI.DOM.makeElement('span', ` For best results, use complete, capitalized and punctuated sentences; for example: '${He} followed you home from the pet store.'`, 'note'));
 		el.appendChild(choices);
 
 		return el;
@@ -2945,17 +2764,13 @@ App.UI.SlaveInteract.custom = (function() {
 		el.appendChild(App.UI.DOM.makeTextBox(
 			slave.custom.desc,
 			v => {
-				slave.custom.desc = v,
-					App.UI.SlaveInteract.custom(slave);
+				slave.custom.desc = v;
+				App.UI.SlaveInteract.custom(slave);
 			}));
 
 		let choices = document.createElement('div');
 		choices.className = "choices";
-
-		let note = document.createElement('span');
-		note.className = "note";
-		note.textContent = ` For best results, use complete, capitalized and punctuated sentences; for example: '${He} has a beauty mark above ${his} left nipple.'`;
-		choices.appendChild(note);
+		choices.appendChild(App.UI.DOM.makeElement('span', ` For best results, use complete, capitalized and punctuated sentences; for example: '${He} has a beauty mark above ${his} left nipple.'`, 'note'));
 		el.appendChild(choices);
 
 		return el;
@@ -2979,17 +2794,13 @@ App.UI.SlaveInteract.custom = (function() {
 		el.appendChild(App.UI.DOM.makeTextBox(
 			slave.custom.label,
 			v => {
-				slave.custom.label = v,
-					App.UI.SlaveInteract.custom(slave);
+				slave.custom.label = v;
+				App.UI.SlaveInteract.custom(slave);
 			}));
 
 		let choices = document.createElement('div');
 		choices.className = "choices";
-
-		let note = document.createElement('span');
-		note.className = "note";
-		note.textContent = ` For best results, use a short phrase; for example: 'Breeder.'`;
-		choices.appendChild(note);
+		choices.appendChild(App.UI.DOM.makeElement('span', ` For best results, use a short phrase; for example: 'Breeder.'`, 'note'));
 		el.appendChild(choices);
 
 		return el;
@@ -3044,9 +2855,9 @@ App.UI.SlaveInteract.custom = (function() {
 			App.UI.DOM.link(
 				` Reset`,
 				() => {
-					slave.custom.image = null,
-						App.UI.SlaveInteract.custom(slave),
-						App.Art.refreshSlaveArt(slave, 3, "artFrame");
+					slave.custom.image = null;
+					App.UI.SlaveInteract.custom(slave);
+					App.Art.refreshSlaveArt(slave, 3, "artFrame");
 				},
 			)
 		);
@@ -3148,17 +2959,17 @@ App.UI.SlaveInteract.custom = (function() {
 			el.appendChild(App.UI.DOM.makeTextBox(
 				slave.custom.hairVector,
 				v => {
-					slave.custom.hairVector = v,
-						App.UI.SlaveInteract.custom(slave);
+					slave.custom.hairVector = v;
+					App.UI.SlaveInteract.custom(slave);
 				}));
 
 			el.appendChild(
 				App.UI.DOM.link(
 					` Reset`,
 					() => {
-						slave.custom.hairVector = 0,
-							App.UI.SlaveInteract.custom(slave),
-							App.Art.refreshSlaveArt(slave, 3, "artFrame");
+						slave.custom.hairVector = 0;
+						App.UI.SlaveInteract.custom(slave);
+						App.Art.refreshSlaveArt(slave, 3, "artFrame");
 					},
 				)
 			);
@@ -3168,7 +2979,40 @@ App.UI.SlaveInteract.custom = (function() {
 	}
 })();
 
-App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck = false) { // category should be in the form of slave.category, the thing we want to update.
+/** @typedef RowItem
+ * @type {object}
+ * @property {string} [FS] - FS requirement, if any
+ * @property {string} [text] - link text
+ * @property {object} [updateSlave] - properties to be merged onto the slave
+ * @property {object} [update] - properties to be merged into global state
+ * @property {string} [disabled] - text indicating why the option is unavailable
+ * @property {string} [note]
+ */
+
+/** Append a simple row of choices with a label to a container, if there are choices to be made.
+ * @param {Node} parent
+ * @param {string} label
+ * @param {RowItem[]} array
+ * @param {App.Entity.SlaveState} slave
+ */
+App.UI.SlaveInteract.appendLabeledChoiceRow = function(parent, label, array, slave) {
+	if (array.length > 0) {
+		let links = document.createElement('div');
+		links.append(`${label}: `);
+		links.appendChild(App.UI.SlaveInteract.generateRows(array, slave));
+		links.className = "choices";
+		return parent.appendChild(links);
+	}
+};
+
+/** Generate a row of choices
+ * @param {RowItem[]} array
+ * @param {App.Entity.SlaveState} slave
+ * @param {string} [category] - should be in the form of slave.category, the thing we want to update.
+ * @param {boolean} [accessCheck=false]
+ * @returns {HTMLSpanElement}
+ */
+App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck = false) {
 	let row = document.createElement('span');
 	let useSep = false;
 	for (let i = 0; i < array.length; i++) {
@@ -3191,9 +3035,9 @@ App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck
 		if (accessCheck === true) {
 			if (category === "chastity") {
 				let text = array[i].text.toLowerCase(); // Yucky. Category name does not match for chastity (since it sets multiple kinds of chastity at once). Compare using a lowercased name instead.
-				unlocked = isItemAccessible.entry(text, `${category}`, slave, true);
+				unlocked = isItemAccessible.entry(text, category, slave);
 			} else {
-				unlocked = isItemAccessible.entry(array[i].updateSlave[category], `${category}`, slave, true);
+				unlocked = isItemAccessible.entry(array[i].updateSlave[category], category, slave);
 			}
 		}
 		if (accessCheck === false || unlocked) {
@@ -3227,10 +3071,7 @@ App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck
 
 				// add a note node if required
 				if (array[i].note) {
-					let note = document.createElement('span');
-					note.textContent = (` ${array[i].note}`);
-					note.className = "note";
-					link.appendChild(note);
+					link.appendChild(App.UI.DOM.makeElement('span', ` ${array[i].note}`, 'note'));
 				}
 			}
 			row.appendChild(link);
@@ -3239,6 +3080,7 @@ App.UI.SlaveInteract.generateRows = function(array, slave, category, accessCheck
 
 	return row;
 
+	/** @param {RowItem} arrayOption */
 	function click(arrayOption) {
 		if (arrayOption.updateSlave) {
 			for (const slaveProperty in arrayOption.updateSlave) {