diff --git a/js/003-data/slaveMods.js b/js/003-data/slaveMods.js
index 781a17b19982bf75c7c2b558769c65df06a4ac3c..b5d8e78164b5f2378e5cb699a66c5dbab78dfc3a 100644
--- a/js/003-data/slaveMods.js
+++ b/js/003-data/slaveMods.js
@@ -191,3 +191,208 @@ App.Medicine.Modification.Brands = {
 		},
 	}
 };
+
+
+App.Medicine.Modification.Color = {
+	Primary: [
+		{value: "auburn"},
+		{value: "black"},
+		{value: "blazing red"},
+		{value: "blonde"},
+		{value: "blue-violet"},
+		{value: "blue"},
+		{value: "brown"},
+		{value: "burgundy"},
+		{value: "chestnut"},
+		{value: "chocolate brown"},
+		{value: "copper"},
+		{value: "dark blue"},
+		{value: "dark brown"},
+		{value: "dark orchid"},
+		{value: "deep red"},
+		{value: "ginger"},
+		{value: "golden"},
+		{value: "green-yellow"},
+		{value: "green"},
+		{value: "grey"},
+		{value: "hazel"},
+		{value: "jet black"},
+		{value: "neon blue"},
+		{value: "neon green"},
+		{value: "neon pink"},
+		{value: "pink"},
+		{value: "platinum blonde"},
+		{value: "purple"},
+		{value: "red"},
+		{value: "sea green"},
+		{value: "silver"},
+		{value: "strawberry-blonde"},
+		{value: "white"},
+	],
+	Secondary: [
+		{
+			title: "None",
+			value: ""
+		},
+		{
+			title: "Black",
+			value: " with black highlights"
+		},
+		{
+			title: "Blazing red",
+			value: " with blazing red highlights"
+		},
+		{
+			title: "Blonde",
+			value: " with blonde highlights"
+		},
+		{
+			title: "Grey",
+			value: " with grey highlights"
+		},
+		{
+			title: "Neon blue",
+			value: " with neon blue highlights"
+		},
+		{
+			title: "Neon green",
+			value: " with neon green highlights"
+		},
+		{
+			title: "Neon pink",
+			value: " with neon pink highlights"
+		},
+		{
+			title: "Rainbow",
+			value: " with rainbow highlights"
+		},
+		{
+			title: "Silver",
+			value: " with silver highlights"
+		},
+		{
+			title: "White",
+			value: " with white highlights"
+		},
+	]
+};
+
+App.Medicine.Modification.hairStyles = {
+	Normal: [
+		{
+			title: "Afro",
+			value: "afro"
+		},
+		{
+			title: "Braided",
+			value: "braided"
+		},
+		{
+			title: "Cornrows",
+			value: "cornrows"
+		},
+		{
+			title: "Curled",
+			value: "curled"
+		},
+		{
+			title: "Dreadlocks",
+			value: "dreadlocks"
+		},
+		{
+			title: "Eary",
+			value: "eary"
+		},
+		{
+			title: "In a bun",
+			value: "bun"
+		},
+		{
+			title: "In a messy bun",
+			value: "messy bun"
+		},
+		{
+			title: "In a ponytail",
+			value: "ponytail"
+		},
+		{
+			title: "In tails",
+			value: "tails"
+		},
+		{
+			title: "Luxurious",
+			value: "luxurious"
+		},
+		{
+			title: "Messy",
+			value: "messy"
+		},
+		{
+			title: "Neat",
+			value: "neat"
+		},
+		{
+			title: "Permed",
+			value: "permed"
+		},
+		{
+			title: "Shaved sides",
+			value: "strip"
+		},
+		{
+			title: "Up",
+			value: "up"
+		},
+	],
+	Cut: [
+		{
+			title: "Shaved",
+			value: "shaved",
+			hLength: 0
+		},
+		{
+			title: "Trimmed short",
+			value: "Salon",
+			hLength: 10
+		},
+		{
+			title: "Buzzcut",
+			value: "buzzcut",
+			hLength: 1
+		},
+	],
+	Length: [
+		{
+			title: "Very short",
+			hLength: 5
+		},
+		{
+			title: "Short",
+			hLength: 10
+		},
+		{
+			title: "Shoulder length",
+			hLength: 30
+		},
+		{
+			title: "Long",
+			hLength: 60
+		},
+		{
+			title: "Very long",
+			hLength: 100
+		},
+		{
+			title: "Apply hair growth stimulating treatment",
+			hLength: 0,
+			requirements: function(slave) { return (slave.hLength === 1); }
+		},
+		{
+			title: "Apply extensions",
+			onApplication: function(slave) { slave.hLength += 10; },
+			requirements: function(slave) { return (!slave.hLength === 1 && slave.hLength < 150); }
+		},
+	]
+};
+
+
diff --git a/src/facilities/nursery/childInteract.tw b/src/facilities/nursery/childInteract.tw
index 8a9b273b086a458bbbaa744d1109ed9c94d4580e..76f18de06ba35e10122e1f6d252958317d3cf364 100644
--- a/src/facilities/nursery/childInteract.tw
+++ b/src/facilities/nursery/childInteract.tw
@@ -60,7 +60,7 @@
 FIXME:
 <br><br>__Take slave to another room:__
 [[Wardrobe|Wardrobe Use][$degradation = 0]]
-| [[Auto salon|Salon][$degradation = 0, $primaryHairColor = "", $secondaryHairColor = "", $tattooChoice = "", $piercingLevel = ""]]
+| [[Auto salon|Salon][$degradation = 0, $tattooChoice = "", $piercingLevel = ""]]
 | [[Body mod studio|Body Modification][$degradation = 0, $tattooChoice = undefined]]
 | [[Remote surgery|Remote Surgery][$degradation = 0]]
 | [[Configure cybernetics|Prosthetics Configuration][$prostheticsConfig = "main"]]
diff --git a/src/interaction/prostheticConfig.tw b/src/interaction/prostheticConfig.tw
index 877537a1241c847647b2e84dc63f7c088cfd41fd..e44f47ea79b77bbb7ccabbac51730ea837bd952d 100644
--- a/src/interaction/prostheticConfig.tw
+++ b/src/interaction/prostheticConfig.tw
@@ -115,7 +115,7 @@ This room is lined with shelves and cabinets; it could be easily mistaken for a
 	</p>
 
 	<p class="indent">
-	$He has <<print App.Desc.eyesColor(getSlave($AS))>>. To change $his eye color visit the [[auto salon|Salon][$primaryHairColor = "", $secondaryHairColor = "", $primaryTailColor = "", $secondaryTailColor = ""]].
+	$He has <<print App.Desc.eyesColor(getSlave($AS))>>. To change $his eye color visit the [[auto salon|Salon][$primaryTailColor = "", $secondaryTailColor = ""]].
 	</p>
 <</if>>
 
diff --git a/src/interaction/slaveInteract.js b/src/interaction/slaveInteract.js
index b47be85bde522fbd72cdaaec260be62462963b03..b4431734faa401fd4c0f0b2b076ed36367e2c22f 100644
--- a/src/interaction/slaveInteract.js
+++ b/src/interaction/slaveInteract.js
@@ -61,8 +61,6 @@ App.UI.SlaveInteract.modify = function(slave) {
 	makeRoomLink(el, "Auto salon", "Salon", ' Modify hair (color, length, style), nails, and even skin color.',
 		() => {
 			V.activeSlave = slave;
-			V.primaryHairColor = "";
-			V.secondaryHairColor = "";
 			V.primaryTailColor = "";
 			V.secondaryTailColor = "";
 		}
diff --git a/src/js/modification.js b/src/js/modification.js
index aaedaf67f8498577e15f90fa6c04ed815924f6e8..2a9358b08cdf07248ec5b33b88270aa6a3782fee 100644
--- a/src/js/modification.js
+++ b/src/js/modification.js
@@ -556,224 +556,3 @@ App.Medicine.Modification.setTattoo = function(slave, location, design) {
 	slave[`${location}Tat`] = design;
 	return r;
 };
-
-/**
- * @param {App.Entity.PlayerState|App.Entity.SlaveState} entity
- * @param {boolean} player
- * @returns {HTMLDivElement}
- */
-App.Medicine.Modification.eyeSelector = function(entity, player = false) {
-	const {He, him, his} = getPronouns(entity);
-
-	let selectedSide = "none";
-	let selectedIris = "none";
-	let selectedPupil = "none";
-	let selectedSclera = "none";
-
-	let removeDiv = document.createElement("div");
-	removeDiv.classList.add("choices");
-	let applyDiv = document.createElement("div");
-
-	const container = document.createElement("div");
-	container.append(
-		`${player ? "You have" : `${He} has`} ${App.Desc.eyesColorLong(entity)}, ${hasBothEyes(
-			entity) ? "they are" : "it is"} ${App.Desc.eyesType(entity)}.`,
-		removeDiv, "You have a number of contact lenses in various colors available. ",
-		App.UI.DOM.makeElement("span", `You can change what ${player ? "your" : his} eyes look like.`, "note"),
-		assembleLinks(), applyDiv
-	);
-	updateRemoveDiv();
-	updateApplyDiv();
-	return container;
-
-	function assembleLinks() {
-		const sides = ["left", "right", "both"];
-		const irisColors = ["amber", "black", "blue", "brown", "green", "hazel", "orange", "pale-grey", "pink", "red",
-			"sky-blue", "turquoise", "white", "yellow"];
-		const pupilShapes = ["none", "circular", "almond-shaped", "bright", "catlike", "demonic", "devilish",
-			"goat-like", "heart-shaped", "hypnotic", "serpent-like", "star-shaped", "teary", "vacant", "wide-eyed"];
-		const scleraColors = ["none", "white", "amber", "black", "blue", "brown", "green", "hazel", "orange",
-			"pale-grey", "pink", "red", "sky-blue", "turquoise", "yellow"];
-		const div = document.createDocumentFragment();
-		div.append(
-			assembleList("Side: ", sides, value => selectedSide = value, selectedIris),
-			assembleList("Iris: ", irisColors, value => selectedIris = value, selectedSide),
-			assembleList("Pupil: ", pupilShapes, value => selectedPupil = value, selectedPupil),
-			assembleList("Sclera: ", scleraColors, value => selectedSclera = value, selectedSclera)
-		);
-		return div;
-	}
-
-	/**
-	 * @param {string} name
-	 * @param {Array<string>} list
-	 * @param {Function}callback
-	 * @param {string} selected
-	 * @returns {HTMLDivElement}
-	 */
-	function assembleList(name, list, callback, selected) {
-		const links = [];
-
-		for (let i = 0; i < list.length; i++) {
-			addToggle(list[i], callback, links, list[i] === selected);
-		}
-
-		const div = document.createElement("div");
-		div.classList.add("choices");
-		div.append(name, App.UI.DOM.arrayToList(links, " | ", " | "));
-		return div;
-	}
-
-	/**
-	 * @param {string} value
-	 * @param {Function} callback
-	 * @param {Array<HTMLAnchorElement>} links
-	 * @param {boolean} [disabled]
-	 */
-	function addToggle(value, callback, links, disabled = false) {
-		const a = document.createElement("a");
-		a.append(capFirstChar(value));
-		if (disabled) {
-			a.classList.add("disabled");
-		}
-		a.onclick = () => {
-			for (let link of links) {
-				link.classList.remove("disabled");
-			}
-			a.classList.add("disabled");
-			callback(value);
-			updateRemoveDiv();
-			updateApplyDiv();
-		};
-		links.push(a);
-	}
-
-	function updateApplyDiv() {
-		$(applyDiv).empty();
-		if (selectedSide !== "none" && selectedIris !== "none") {
-			// make the following easier to read
-			let both = selectedSide === "both";
-			let leftGlass = !hasLeftEye(entity) || getLeftEyeType(entity) === 2;
-			let rightGlass = !hasRightEye(entity) || getRightEyeType(entity) === 2;
-
-			// base eye
-			let r = player ? "" : ` ${him}`;
-			if (both) {
-				if (leftGlass && rightGlass) {
-					r += ` ${selectedIris} glass eyes`;
-				} else if (leftGlass || rightGlass) {
-					r += ` a glass eye and a ${selectedIris} lens`;
-				} else {
-					r += ` ${selectedIris} lenses`;
-				}
-			} else {
-				r += " a";
-				if ((selectedSide === "left" && leftGlass) || (selectedSide === "right" && rightGlass)) {
-					r += ` ${selectedIris} glass eye`;
-				} else {
-					r += ` ${selectedIris} lens`;
-				}
-			}
-			// pupil & sclera
-			if (selectedPupil !== "none" || selectedSclera !== "none") {
-				r += " with";
-				if (selectedPupil !== "none") {
-					r += ` ${both ? selectedPupil : addA(selectedPupil)}`;
-					if (both) {
-						r += " pupils";
-					} else {
-						r += " pupil";
-					}
-					if (selectedSclera !== "none") {
-						r += " and";
-					}
-				}
-				if (selectedSclera !== "none") {
-					r += ` ${selectedSclera}`;
-					if (both) {
-						r += " sclerae";
-					} else {
-						r += " sclera";
-					}
-				}
-			}
-			if (!both) {
-				r += ` for ${player ? "your" : his} ${selectedSide} eye`;
-			}
-			r += "?";
-
-			const a = document.createElement("a");
-			a.append(player ? "Take" : "Give");
-			a.onclick = applyLink;
-			applyDiv.append(a, r);
-			if (!player) {
-				applyDiv.append(" ",
-					App.UI.DOM.makeElement("span", "This is independent from eyewear choices.", "note"));
-			}
-		}
-	}
-
-	function applyLink() {
-		// make sure the eye exists; give glass eye if there is none
-		if ((selectedSide === "left" || selectedSide === "both") && getLeftEyeType(entity) === 0) {
-			eyeSurgery(entity, "left", "glass");
-		}
-		if ((selectedSide === "right" || selectedSide === "both") && getRightEyeType(entity) === 0) {
-			eyeSurgery(entity, "right", "glass");
-		}
-
-		// apply modifications
-		setEyeColorFull(entity, selectedIris,
-			selectedPupil === "none" ? "" : selectedPupil,
-			selectedSclera === "none" ? "" : selectedSclera,
-			selectedSide);
-		cashX(forceNeg(V.modCost), "slaveMod", entity);
-
-		App.UI.reload();
-	}
-
-
-	function updateRemoveDiv() {
-		$(removeDiv).empty();
-		const links = [];
-		let _n = 0;
-		// remove lenses
-		if (hasLeftEye(entity) && getLeftEyeColor(entity) !== getGeneticEyeColor(entity, "left")) {
-			_n++;
-			links.push(removeLink("Remove left lens", () => resetEyeColor(entity, "left")));
-		}
-		if (hasRightEye(entity) && getRightEyeColor(entity) !== getGeneticEyeColor(entity, "right")) {
-			_n++;
-			links.push(removeLink("Remove right lens", () => resetEyeColor(entity, "right")));
-		}
-		if (_n === 2) {
-			links.push(removeLink("Remove both lenses", () => resetEyeColor(entity, "both")));
-		}
-		// remove glass eyes
-		_n = 0;
-		if (getLeftEyeType(entity) === 2) {
-			_n++;
-			links.push(removeLink("Remove left glass eye", () => eyeSurgery(entity, "left", "remove")));
-		}
-		if (getRightEyeType(entity) === 2) {
-			_n++;
-			links.push(removeLink("Remove right glass eye", () => eyeSurgery(entity, "right", "remove")));
-		}
-		if (_n === 2) {
-			links.push(removeLink("Remove both glass eyes", () => eyeSurgery(entity, "both", "remove")));
-		}
-		if (links.length > 0) {
-			removeDiv.append(App.UI.DOM.arrayToList(links, " | ", " | "));
-		}
-	}
-
-	function removeLink(text, callback) {
-		const a = document.createElement("a");
-		a.append(text);
-		a.onclick = () => {
-			callback();
-			App.UI.reload();
-		};
-		return a;
-	}
-};
diff --git a/src/js/salon.js b/src/js/salon.js
index 812dee1f258f663bbfcddef16011b2301b6ce023..5892475b4a20ba21710e9910a363db3a14d171d3 100644
--- a/src/js/salon.js
+++ b/src/js/salon.js
@@ -1,11 +1,235 @@
+/**
+ * @param {App.Entity.PlayerState|App.Entity.SlaveState} entity
+ * @param {boolean} player
+ * @returns {HTMLDivElement}
+ */
+App.Medicine.Modification.eyeSelector = function(entity, player = false) {
+	const {He, him, his} = getPronouns(entity);
+
+	let selectedSide = "none";
+	let selectedIris = "none";
+	let selectedPupil = "none";
+	let selectedSclera = "none";
+
+	let removeDiv = document.createElement("div");
+	removeDiv.classList.add("choices");
+	let applyDiv = document.createElement("div");
+
+	const container = document.createElement("div");
+	container.append(
+		`${player ? "You have" : `${He} has`} ${App.Desc.eyesColorLong(entity)}, ${hasBothEyes(
+			entity) ? "they are" : "it is"} ${App.Desc.eyesType(entity)}.`,
+		removeDiv, "You have a number of contact lenses in various colors available. ",
+		App.UI.DOM.makeElement("span", `You can change what ${player ? "your" : his} eyes look like.`, "note"),
+		assembleLinks(), applyDiv
+	);
+	updateRemoveDiv();
+	updateApplyDiv();
+	return container;
+
+	function assembleLinks() {
+		const sides = ["left", "right", "both"];
+		const irisColors = ["amber", "black", "blue", "brown", "green", "hazel", "orange", "pale-grey", "pink", "red",
+			"sky-blue", "turquoise", "white", "yellow"];
+		const pupilShapes = ["none", "circular", "almond-shaped", "bright", "catlike", "demonic", "devilish",
+			"goat-like", "heart-shaped", "hypnotic", "serpent-like", "star-shaped", "teary", "vacant", "wide-eyed"];
+		const scleraColors = ["none", "white", "amber", "black", "blue", "brown", "green", "hazel", "orange",
+			"pale-grey", "pink", "red", "sky-blue", "turquoise", "yellow"];
+		const div = document.createDocumentFragment();
+		div.append(
+			assembleList("Side: ", sides, value => selectedSide = value, selectedIris),
+			assembleList("Iris: ", irisColors, value => selectedIris = value, selectedSide),
+			assembleList("Pupil: ", pupilShapes, value => selectedPupil = value, selectedPupil),
+			assembleList("Sclera: ", scleraColors, value => selectedSclera = value, selectedSclera)
+		);
+		return div;
+	}
+
+	/**
+	 * @param {string} name
+	 * @param {Array<string>} list
+	 * @param {Function}callback
+	 * @param {string} selected
+	 * @returns {HTMLDivElement}
+	 */
+	function assembleList(name, list, callback, selected) {
+		const links = [];
+
+		for (let i = 0; i < list.length; i++) {
+			addToggle(list[i], callback, links, list[i] === selected);
+		}
+
+		const div = document.createElement("div");
+		div.classList.add("choices");
+		div.append(name, App.UI.DOM.arrayToList(links, " | ", " | "));
+		return div;
+	}
+
+	/**
+	 * @param {string} value
+	 * @param {Function} callback
+	 * @param {Array<HTMLAnchorElement>} links
+	 * @param {boolean} [disabled]
+	 */
+	function addToggle(value, callback, links, disabled = false) {
+		const a = document.createElement("a");
+		a.append(capFirstChar(value));
+		if (disabled) {
+			a.classList.add("disabled");
+		}
+		a.onclick = () => {
+			for (let link of links) {
+				link.classList.remove("disabled");
+			}
+			a.classList.add("disabled");
+			callback(value);
+			updateRemoveDiv();
+			updateApplyDiv();
+		};
+		links.push(a);
+	}
+
+	function updateApplyDiv() {
+		$(applyDiv).empty();
+		if (selectedSide !== "none" && selectedIris !== "none") {
+			// make the following easier to read
+			let both = selectedSide === "both";
+			let leftGlass = !hasLeftEye(entity) || getLeftEyeType(entity) === 2;
+			let rightGlass = !hasRightEye(entity) || getRightEyeType(entity) === 2;
+
+			// base eye
+			let r = player ? "" : ` ${him}`;
+			if (both) {
+				if (leftGlass && rightGlass) {
+					r += ` ${selectedIris} glass eyes`;
+				} else if (leftGlass || rightGlass) {
+					r += ` a glass eye and a ${selectedIris} lens`;
+				} else {
+					r += ` ${selectedIris} lenses`;
+				}
+			} else {
+				r += " a";
+				if ((selectedSide === "left" && leftGlass) || (selectedSide === "right" && rightGlass)) {
+					r += ` ${selectedIris} glass eye`;
+				} else {
+					r += ` ${selectedIris} lens`;
+				}
+			}
+			// pupil & sclera
+			if (selectedPupil !== "none" || selectedSclera !== "none") {
+				r += " with";
+				if (selectedPupil !== "none") {
+					r += ` ${both ? selectedPupil : addA(selectedPupil)}`;
+					if (both) {
+						r += " pupils";
+					} else {
+						r += " pupil";
+					}
+					if (selectedSclera !== "none") {
+						r += " and";
+					}
+				}
+				if (selectedSclera !== "none") {
+					r += ` ${selectedSclera}`;
+					if (both) {
+						r += " sclerae";
+					} else {
+						r += " sclera";
+					}
+				}
+			}
+			if (!both) {
+				r += ` for ${player ? "your" : his} ${selectedSide} eye`;
+			}
+			r += "?";
+
+			const a = document.createElement("a");
+			a.append(player ? "Take" : "Give");
+			a.onclick = applyLink;
+			applyDiv.append(a, r);
+			if (!player) {
+				applyDiv.append(" ",
+					App.UI.DOM.makeElement("span", "This is independent from eyewear choices.", "note"));
+			}
+		}
+	}
+
+	function applyLink() {
+		// make sure the eye exists; give glass eye if there is none
+		if ((selectedSide === "left" || selectedSide === "both") && getLeftEyeType(entity) === 0) {
+			eyeSurgery(entity, "left", "glass");
+		}
+		if ((selectedSide === "right" || selectedSide === "both") && getRightEyeType(entity) === 0) {
+			eyeSurgery(entity, "right", "glass");
+		}
+
+		// apply modifications
+		setEyeColorFull(entity, selectedIris,
+			selectedPupil === "none" ? "" : selectedPupil,
+			selectedSclera === "none" ? "" : selectedSclera,
+			selectedSide);
+		cashX(forceNeg(V.modCost), "slaveMod", entity);
+
+		App.UI.reload();
+	}
+
+	function updateRemoveDiv() {
+		$(removeDiv).empty();
+		const links = [];
+		let _n = 0;
+		// remove lenses
+		if (hasLeftEye(entity) && getLeftEyeColor(entity) !== getGeneticEyeColor(entity, "left")) {
+			_n++;
+			links.push(removeLink("Remove left lens", () => resetEyeColor(entity, "left")));
+		}
+		if (hasRightEye(entity) && getRightEyeColor(entity) !== getGeneticEyeColor(entity, "right")) {
+			_n++;
+			links.push(removeLink("Remove right lens", () => resetEyeColor(entity, "right")));
+		}
+		if (_n === 2) {
+			links.push(removeLink("Remove both lenses", () => resetEyeColor(entity, "both")));
+		}
+		// remove glass eyes
+		_n = 0;
+		if (getLeftEyeType(entity) === 2) {
+			_n++;
+			links.push(removeLink("Remove left glass eye", () => eyeSurgery(entity, "left", "remove")));
+		}
+		if (getRightEyeType(entity) === 2) {
+			_n++;
+			links.push(removeLink("Remove right glass eye", () => eyeSurgery(entity, "right", "remove")));
+		}
+		if (_n === 2) {
+			links.push(removeLink("Remove both glass eyes", () => eyeSurgery(entity, "both", "remove")));
+		}
+		if (links.length > 0) {
+			removeDiv.append(App.UI.DOM.arrayToList(links, " | ", " | "));
+		}
+	}
+
+	function removeLink(text, callback) {
+		const a = document.createElement("a");
+		a.append(text);
+		a.onclick = () => {
+			callback();
+			App.UI.reload();
+		};
+		return a;
+	}
+};
+
 /**
  * Update ears in salon
  * @param {App.Entity.SlaveState} slave
- * @param {object}
+ * @param {object} params
+ * @param {number|string} [params.primaryEarColor]
+ * @param {string} [params.secondaryEarColor]
  * @returns {node}
  */
 App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColor = ""} = {}) {
 	const frag = new DocumentFragment();
+	let updatePrimary = (newVal) => { primaryEarColor = newVal; apply(); };
+	let updateSecondary = (newVal) => { secondaryEarColor = newVal; apply(); };
 
 	if (slave.earT !== "none" && slave.earTColor !== "hairless") {
 		const {His, his} = getPronouns(slave);
@@ -21,6 +245,7 @@ App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColo
 					"Match current hair",
 					() => {
 						slave.earTColor = slave.hColor;
+						App.Art.refreshSlaveArt(slave, 3, "artFrame");
 						apply();
 					}
 				)
@@ -34,98 +259,14 @@ App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColo
 
 		div = document.createElement("div");
 		div.classList.add("choices");
-		div.append(`Colors: `);
-
-		const primaryEarColorArray = [
-			"auburn",
-			"black",
-			"blazing red",
-			"blonde",
-			"blue-violet",
-			"blue",
-			"brown",
-			"burgundy",
-			"chestnut",
-			"chocolate brown",
-			"copper",
-			"dark blue",
-			"dark brown",
-			"dark orchid",
-			"deep red",
-			"ginger",
-			"golden",
-			"green-yellow",
-			"green",
-			"grey",
-			"hazel",
-			"jet black",
-			"neon blue",
-			"neon green",
-			"neon pink",
-			"pink",
-			"platinum blonde",
-			"purple",
-			"red",
-			"sea green",
-			"silver",
-			"strawberry-blonde",
-			"white",
-		];
-
-		div.append(createList(primaryEarColorArray));
+		div.append(`Colors:`);
+		div.append(createList(App.Medicine.Modification.Color.Primary, updatePrimary));
 		frag.append(div);
 
-
 		div = document.createElement("div");
 		div.classList.add("choices");
-		div.append(`Highlights: `);
-		const secondaryEarColorArray = [
-			{
-				title: "None",
-				value: ""
-			},
-			{
-				title: "Black",
-				value: " with black highlights"
-			},
-			{
-				title: "Blazing red",
-				value: " with blazing red highlights"
-			},
-			{
-				title: "Blonde",
-				value: " with blonde highlights"
-			},
-			{
-				title: "Grey",
-				value: " with grey highlights"
-			},
-			{
-				title: "Neon blue",
-				value: " with neon blue highlights"
-			},
-			{
-				title: "Neon green",
-				value: " with neon green highlights"
-			},
-			{
-				title: "Neon pink",
-				value: " with neon pink highlights"
-			},
-			{
-				title: "Rainbow",
-				value: " with rainbow highlights"
-			},
-			{
-				title: "Silver",
-				value: " with silver highlights"
-			},
-			{
-				title: "White",
-				value: " with white highlights"
-			},
-		];
-		div.append(createList(secondaryEarColorArray));
+		div.append(`Highlights:`);
+		div.append(createList(App.Medicine.Modification.Color.Secondary, updateSecondary));
 		frag.append(div);
 
 		if (primaryEarColor !== 0) {
@@ -133,9 +274,10 @@ App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColo
 			p.classList.add("choices");
 			p.append(
 				App.UI.DOM.link(
-					`Dye ${his} ears`,
+					`Color ${his} ears`,
 					() => {
 						slave.earTColor = (primaryEarColor + secondaryEarColor);
+						App.Art.refreshSlaveArt(slave, 3, "artFrame");
 						cashX(forceNeg(V.modCost), "slaveMod", slave);
 						App.Medicine.Salon.ears(slave); // discard selections after locking them in.
 					}
@@ -147,35 +289,21 @@ App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColo
 	}
 	return jQuery("#salonEars").empty().append(frag);
 
-	function createList(array) {
+	function createList(array, method) {
 		const links = [];
 		for (const item of array) {
-			if (typeof item === "string") {
-				links.push(
-					App.UI.DOM.link(
-						capFirstChar(item),
-						() => {
-							primaryEarColor = item;
-							apply();
-						}
-					)
-				);
-			} else {
-				const title = item.title || capFirstChar(item.value);
-				links.push(
-					App.UI.DOM.link(
-						title,
-						() => {
-							secondaryEarColor = item.value;
-							apply();
-						}
-					)
-				);
-			}
+			const title = item.title || capFirstChar(item.value);
+			links.push(
+				App.UI.DOM.link(
+					title,
+					() => method(item.value)
+				)
+			);
 		}
 		return App.UI.DOM.generateLinksStrip(links);
 	}
 	function apply() {
+		App.Art.refreshSlaveArt(slave, 3, "artFrame");
 		App.Medicine.Salon.ears(
 			slave,
 			{
@@ -185,3 +313,370 @@ App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColo
 		);
 	}
 };
+
+/**
+ * Update hair in salon
+ * @param {App.Entity.SlaveState} slave
+ * @param {object} params
+ * @param {number|string} [params.primaryHairColor]
+ * @param {string} [params.secondaryHairColor]
+ * @returns {node}
+ */
+App.Medicine.Salon.hair = function(slave, {primaryHairColor = 0, secondaryHairColor = ""} = {}) {
+	const frag = new DocumentFragment();
+	let updatePrimary = (newVal) => { primaryHairColor = newVal.value; apply(); };
+	let updateSecondary = (newVal) => { secondaryHairColor = newVal.value; apply(); };
+	const {His, his, He, him} = getPronouns(slave);
+
+	if (slave.bald !== 1) {
+		frag.append(hairDye());
+		frag.append(hairStyle());
+		frag.append(hairLength());
+		frag.append(hairMaint());
+	} else {
+		// Bald
+		if (slave.hStyle === "bald") {
+			frag.append(`${He} is completely bald.`);
+		} else {
+			frag.append(wigDye());
+		}
+		frag.append(wigStyle());
+		frag.append(wigLength());
+	}
+	return jQuery("#salonHair").empty().append(frag);
+
+	function hairDye() {
+		const frag = new DocumentFragment();
+		let div;
+		let p;
+		frag.append(`${His} hair is ${slave.hColor}.`);
+
+		div = document.createElement("div");
+		div.classList.add("choices");
+		if (slave.origHColor !== slave.hColor) {
+			div.append(
+				App.UI.DOM.link(
+					"Restore natural color",
+					() => {
+						slave.hColor = slave.origHColor;
+						apply();
+					}
+				)
+			);
+			div.append(" or ");
+			App.UI.DOM.appendNewElement("span", div, "choose a new one: ", "note");
+		} else {
+			App.UI.DOM.appendNewElement("span", div, `Choose a dye color before dyeing ${his} hair:`, "note");
+		}
+		frag.append(div);
+
+		div = document.createElement("div");
+		div.classList.add("choices");
+		div.append(`Colors:`);
+		div.append(createList(App.Medicine.Modification.Color.Primary, updatePrimary));
+		frag.append(div);
+
+		div = document.createElement("div");
+		div.classList.add("choices");
+		div.append(`Highlights:`);
+		div.append(createList(App.Medicine.Modification.Color.Secondary, updateSecondary));
+		frag.append(div);
+
+		if (primaryHairColor !== 0) {
+			p = document.createElement("p");
+			p.classList.add("choices");
+			p.append(
+				App.UI.DOM.link(
+					`Color ${his} hair`,
+					() => {
+						slave.hColor = (primaryHairColor + secondaryHairColor);
+						App.Art.refreshSlaveArt(slave, 3, "artFrame");
+						cashX(forceNeg(V.modCost), "slaveMod", slave);
+						App.Medicine.Salon.hair(slave); // discard selections after locking them in.
+					}
+				)
+			);
+			p.append(` ${primaryHairColor}${secondaryHairColor} now?`);
+			frag.append(p);
+		}
+		return frag;
+	}
+
+	function hairStyle() {
+		const frag = new DocumentFragment();
+		let div;
+		let method;
+		div = document.createElement("div");
+		if (slave.hStyle !== "shaved") {
+			div.append(`${His} ${slave.hStyle} hair is ${lengthToEitherUnit(slave.hLength)} long. `);
+		} else {
+			div.append(`${His} hair is shaved smooth. `);
+		}
+		App.UI.DOM.appendNewElement("span", div, `General hairstyles will conform to hair length and clothing choices.`, "note");
+		frag.append(div);
+
+		// Normal styles
+		div = document.createElement("div");
+		div.classList.add("choices");
+		method = (newVal) => {
+			slave.hStyle = newVal.value;
+			cashX(forceNeg(V.modCost), "slaveMod", slave);
+			apply();
+		};
+		if (slave.hLength > 1) {
+			div.append(`Style ${his} hair:`);
+			div.append(createList(App.Medicine.Modification.hairStyles.Normal, method));
+		} else {
+			App.UI.DOM.appendNewElement("span", div, `${His} hair is too short to style meaningfully`, "note");
+		}
+		frag.append(div);
+
+		// Short styles, includes cutting
+		div = document.createElement("div");
+		div.classList.add("choices");
+		method = (newVal) => {
+			slave.hStyle = newVal.value;
+			slave.hLength = newVal.hLength;
+			cashX(forceNeg(V.modCost), "slaveMod", slave);
+			apply();
+		};
+		if (slave.hLength > 1) {
+			div.append(`Cut and style ${his} hair:`);
+			div.append(createList(App.Medicine.Modification.hairStyles.Cut, method));
+		}
+		frag.append(div);
+
+		return frag;
+	}
+
+	function hairLength() {
+		const frag = new DocumentFragment();
+		let div = document.createElement("div");
+		div.classList.add("choices");
+		let method = (newVal) => {
+			if (newVal.hasOwnProperty("onApplication")) {
+				newVal.onApplication(slave);
+			}
+			if (newVal.hasOwnProperty("hLength")) {
+				slave.hLength = newVal.hLength;
+			}
+			apply();
+		};
+		const oldHLength = (V.showInches === 2) ? Math.round(slave.hLength/2.54) : slave.hLength;
+
+		App.UI.DOM.appendNewElement("span", div, `Cut or lengthen ${his} hair:`);
+		div.append(createList(App.Medicine.Modification.hairStyles.Length, method));
+		div.append(" | Custom length: ");
+		div.append(
+			App.UI.DOM.makeTextBox(
+				oldHLength,
+				v => {
+					v = Math.max(v, 0); // Positive hair length only
+					// If they entered "inches," convert
+					if (V.showInches === 2) {
+						v = Math.round(v*2.54);
+					}
+					slave.hLength = v;
+					cashX(forceNeg(V.modCost), "slaveMod", slave);
+					apply();
+				},
+				true
+			)
+		);
+		if (V.showInches === 1) {
+			div.append(`cm (${cmToInchString(slave.hLength)})`);
+		} else if (V.showInches === 2) {
+			div.append(`inches`);
+		}
+
+		frag.append(div);
+
+		return frag;
+	}
+
+	function hairMaint() {
+		let div = document.createElement("div");
+		div.classList.add("choices");
+		div.append(`Have ${his} hair carefully maintained at its current length: `);
+		let haircuts;
+		let text;
+		if (slave.haircuts === 1) {
+			text = "Cease maintenance";
+			haircuts = 0;
+		} else {
+			text = "Begin maintenance";
+			haircuts = 1;
+		}
+		div.append(
+			App.UI.DOM.link(
+				text,
+				() => slave.haircuts = haircuts
+			)
+		);
+		return div;
+	}
+
+	function wigDye() {
+		const frag = new DocumentFragment();
+		let div;
+		let p;
+		frag.append(`${His} current wig is ${slave.hColor}. `);
+
+		if (slave.hStyle !== "bald") {
+			frag.append(
+				App.UI.DOM.link(
+					"Remove wig",
+					() => {
+						slave.hStyle = "bald";
+						slave.hLength = 0;
+						// I'm not going to charge you for taking off a fucking wig.
+						apply();
+					}
+				)
+			);
+			frag.append(" or ");
+			App.UI.DOM.appendNewElement("span", frag, "choose a new one: ", "note");
+		} else {
+			App.UI.DOM.appendNewElement("span", frag, `Choose a wig color:`, "note");
+		}
+
+		div = document.createElement("div");
+		div.classList.add("choices");
+		div.append(`Colors:`);
+		div.append(createList(App.Medicine.Modification.Color.Primary, updatePrimary));
+		frag.append(div);
+
+		div = document.createElement("div");
+		div.classList.add("choices");
+		div.append(`Highlights:`);
+		div.append(createList(App.Medicine.Modification.Color.Secondary, updateSecondary));
+		frag.append(div);
+
+		if (primaryHairColor !== 0) {
+			p = document.createElement("p");
+			p.classList.add("choices");
+			p.append(
+				App.UI.DOM.link(
+					`Change`,
+					() => {
+						slave.earTColor = (primaryHairColor + secondaryHairColor);
+						App.Art.refreshSlaveArt(slave, 3, "artFrame");
+						cashX(forceNeg(V.modCost), "slaveMod", slave);
+						App.Medicine.Salon.hair(slave); // discard selections after locking them in.
+					}
+				)
+			);
+			p.append(` ${his} wig color to ${primaryHairColor}${secondaryHairColor} now?`);
+			frag.append(p);
+		}
+		return frag;
+	}
+
+	function wigLength() {
+		const frag = new DocumentFragment();
+		if (slave.hStyle === "bald") {
+			return frag;
+		}
+		let div = document.createElement("div");
+		div.classList.add("choices");
+		const array = [];
+		for (const number of [10, 30, 60, 90, 120, 150]) {
+			const obj = {};
+			obj.title = lengthToEitherUnit(number);
+			obj.hLength = number;
+			array.push(obj);
+		}
+		let method = (newVal) => {
+			slave.hLength = newVal.hLength;
+			apply();
+		};
+		const oldHLength = (V.showInches === 2) ? Math.round(slave.hLength/2.54) : slave.hLength;
+		App.UI.DOM.appendNewElement("span", div, `Set wig length to:`, "choices");
+		div.append(createList(array, method));
+		div.append(" | Custom length: ");
+		div.append(
+			App.UI.DOM.makeTextBox(
+				oldHLength,
+				v => {
+					v = Math.max(v, 10); // Wigs must be at least 10 cm
+					// If they entered "inches," convert
+					if (V.showInches === 2) {
+						v = Math.round(v*2.54);
+					}
+					slave.hLength = v;
+					cashX(forceNeg(V.modCost), "slaveMod", slave);
+					apply();
+				},
+				true
+			)
+		);
+		if (V.showInches === 1) {
+			div.append(`cm (${cmToInchString(slave.hLength)})`);
+		} else if (V.showInches === 2) {
+			div.append(`inches`);
+		}
+
+		frag.append(div);
+
+		return frag;
+	}
+
+	function wigStyle() {
+		const frag = new DocumentFragment();
+		let div = document.createElement("div");
+		div.classList.add("choices");
+		const method = (newVal) => {
+			slave.hStyle = newVal.value;
+			cashX(forceNeg(V.modCost), "slaveMod", slave);
+			apply();
+		};
+
+		if (slave.hStyle !== "bald") {
+			frag.append(`${His} ${slave.hStyle} wig is ${lengthToEitherUnit(slave.hLength)} long. `);
+		} else {
+			frag.append(`${He} is not wearing a wig. `);
+		}
+		App.UI.DOM.appendNewElement("span", frag, `General hairstyles will conform to hair length and clothing choices.`, "note");
+
+		div = document.createElement("div");
+		div.classList.add("choices");
+		if (slave.hStyle === "bald") {
+			div.append(`Give ${him} a wig:`);
+		} else {
+			div.append(`Set wig style:`);
+		}
+		div.append(createList(App.Medicine.Modification.hairStyles.Normal, method));
+		frag.append(div);
+		return frag;
+	}
+
+	function createList(array, method) {
+		const links = [];
+		for (const item of array) {
+			if (item.hasOwnProperty("requirements")) {
+				if (item.requirements(slave) === false) {
+					continue;
+				}
+			}
+			const title = item.title || capFirstChar(item.value);
+			links.push(
+				App.UI.DOM.link(
+					title,
+					() => method(item)
+				)
+			);
+		}
+		return App.UI.DOM.generateLinksStrip(links);
+	}
+
+	function apply() {
+		App.Art.refreshSlaveArt(slave, 3, "artFrame");
+		App.Medicine.Salon.hair(
+			slave,
+			{
+				primaryHairColor: primaryHairColor,
+				secondaryHairColor: secondaryHairColor,
+			}
+		);
+	}
+};
diff --git a/src/uncategorized/salon.tw b/src/uncategorized/salon.tw
index a15e95da093ed093715f64a285bd79a3c3314f20..8f92721d5448b2f3dbf03ec38ceecb13b7d9c512 100644
--- a/src/uncategorized/salon.tw
+++ b/src/uncategorized/salon.tw
@@ -17,13 +17,15 @@
 </span>
 
 /* 000-250-006 */
-<<if $seeImages == 1>>
-	<<if $imageChoice == 1>>
-		<div class="imageRef lrgVector"><div class="mask">&nbsp;</div><<= SlaveArt(getSlave($AS), 3, 0)>></div>
-	<<else>>
-		<div class="imageRef lrgRender"><div class="mask">&nbsp;</div><<= SlaveArt(getSlave($AS), 3, 0)>></div>
+<span id="artFrame">
+	<<if $seeImages == 1>>
+		<<if $imageChoice == 1>>
+			<div class="imageRef lrgVector"><div class="mask">&nbsp;</div><<= SlaveArt(getSlave($AS), 3, 0)>></div>
+		<<else>>
+			<div class="imageRef lrgRender"><div class="mask">&nbsp;</div><<= SlaveArt(getSlave($AS), 3, 0)>></div>
+		<</if>>
 	<</if>>
-<</if>>
+</span>
 /* 000-250-006 */
 
 /* EYES */
@@ -154,267 +156,11 @@
 /* HAIR */
 
 <h3>Hair</h3>
-<div>
-	<<if getSlave($AS).bald != 1>>
-		$His hair is <<= getSlave($AS).hColor>>.
-		<<if getSlave($AS).origHColor != getSlave($AS).hColor>>
-			[[Restore natural color|Salon][getSlave($AS).hColor = getSlave($AS).origHColor]] or <span class="note">choose a new one:</span>
-		<<else>>
-			<span class="note">Choose a dye color before dyeing $his hair:</span>
-		<</if>>
-		<div class="choices">
-			Colors:
-				[[Auburn|Salon][$primaryHairColor = "auburn"]]
-				| [[Black|Salon][$primaryHairColor = "black"]]
-				| [[Blazing Red|Salon][$primaryHairColor = "blazing red"]]
-				| [[Blonde|Salon][$primaryHairColor = "blonde"]]
-				| [[Blue-Violet|Salon][$primaryHairColor = "blue-violet"]]
-				| [[Blue|Salon][$primaryHairColor = "blue"]]
-				| [[Brown|Salon][$primaryHairColor = "brown"]]
-				| [[Burgundy|Salon][$primaryHairColor = "burgundy"]]
-				| [[Chestnut|Salon][$primaryHairColor = "chestnut"]]
-				| [[Chocolate|Salon][$primaryHairColor = "chocolate brown"]]
-				| [[Copper|Salon][$primaryHairColor = "copper"]]
-				| [[Dark Blue|Salon][$primaryHairColor = "dark blue"]]
-				| [[Dark Brown|Salon][$primaryHairColor = "dark brown"]]
-				| [[Dark Orchid|Salon][$primaryHairColor = "dark orchid"]]
-				| [[Deep Red|Salon][$primaryHairColor = "deep red"]]
-				| [[Ginger|Salon][$primaryHairColor = "ginger"]]
-				| [[Golden|Salon][$primaryHairColor = "golden"]]
-				| [[Green-yellow|Salon][$primaryHairColor = "green-yellow"]]
-				| [[Green|Salon][$primaryHairColor = "green"]]
-				| [[Grey|Salon][$primaryHairColor = "grey"]]
-				| [[Hazel|Salon][$primaryHairColor = "hazel"]]
-				| [[Jet Black|Salon][$primaryHairColor = "jet black"]]
-				| [[Neon Blue|Salon][$primaryHairColor = "neon blue"]]
-				| [[Neon Green|Salon][$primaryHairColor = "neon green"]]
-				| [[Neon Pink|Salon][$primaryHairColor = "neon pink"]]
-				| [[Pink|Salon][$primaryHairColor = "pink"]]
-				| [[Platinum Blonde|Salon][$primaryHairColor = "platinum blonde"]]
-				| [[Purple|Salon][$primaryHairColor = "purple"]]
-				| [[Red|Salon][$primaryHairColor = "red"]]
-				| [[Sea Green|Salon][$primaryHairColor = "sea green"]]
-				| [[Silver|Salon][$primaryHairColor = "silver"]]
-				| [[Strawberry-Blonde|Salon][$primaryHairColor = "strawberry-blonde"]]
-				| [[White|Salon][$primaryHairColor = "white"]]
-		</div>
-
-		<div class="choices">
-			Highlights:
-				[[None|Salon][$secondaryHairColor = ""]]
-				| [[Black|Salon][$secondaryHairColor = " with black highlights"]]
-				| [[Blazing Red|Salon][$secondaryHairColor = " with blazing red highlights"]]
-				| [[Blonde|Salon][$secondaryHairColor = " with blonde highlights"]]
-				| [[Grey|Salon][$secondaryHairColor = " with grey highlights"]]
-				| [[Neon Blue|Salon][$secondaryHairColor = " with neon blue highlights"]]
-				| [[Neon Green|Salon][$secondaryHairColor = " with neon green highlights"]]
-				| [[Neon Pink|Salon][$secondaryHairColor = " with neon pink highlights"]]
-				| [[Rainbow|Salon][$secondaryHairColor = " with rainbow highlights"]]
-				| [[Silver|Salon][$secondaryHairColor = " with silver highlights"]]
-				| [[White|Salon][$secondaryHairColor = " with white highlights"]]
-		</div>
-
-		<<if $primaryHairColor != 0>>
-			<div class="choices">
-				[["Dye " + $his + " hair"|Salon][getSlave($AS).hColor = ($primaryHairColor + $secondaryHairColor),cashX(forceNeg($modCost), "slaveMod", getSlave($AS)), $primaryHairColor = 0, $secondaryHairColor = ""]] $primaryHairColor $secondaryHairColor now?
-			</div>
-		<</if>>
-
-		<div>
-			<<if getSlave($AS).hStyle !== "shaved">>
-				$His <<= getSlave($AS).hStyle>> hair is <<= lengthToEitherUnit(getSlave($AS).hLength)>> long.
-			<<else>>
-				$His hair is shaved smooth.
-			<</if>>
-			<span class="note">General hairstyles will conform to hair length and clothing choices.</span>
-		</div>
-		<div class="choices">
-			<<if getSlave($AS).hLength > 1>>
-				Style $his hair:
-				[[Afro|Salon][getSlave($AS).hStyle = "afro",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Braided|Salon][getSlave($AS).hStyle = "braided",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Cornrows|Salon][getSlave($AS).hStyle = "cornrows",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Curled|Salon][getSlave($AS).hStyle = "curled",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Dreadlocks|Salon][getSlave($AS).hStyle = "dreadlocks",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Eary|Salon][getSlave($AS).hStyle = "eary",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In a bun|Salon][getSlave($AS).hStyle = "bun",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In a messy bun|Salon][getSlave($AS).hStyle = "messy bun",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In a ponytail|Salon][getSlave($AS).hStyle = "ponytail",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In tails|Salon][getSlave($AS).hStyle = "tails",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Luxurious|Salon][getSlave($AS).hStyle = "luxurious",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Messy|Salon][getSlave($AS).hStyle = "messy",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Neat|Salon][getSlave($AS).hStyle = "neat",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Permed|Salon][getSlave($AS).hStyle = "permed",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Shaved sides|Salon][getSlave($AS).hStyle = "strip",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Up|Salon][getSlave($AS).hStyle = "up",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<<else>>
-				<span class="note">$His hair is too short to style meaningfully</span>
-			<</if>>
-		</div>
-
-		<div class="choices">
-			<<if getSlave($AS).hLength > 1>>
-				Cut and style $his hair:
-				[[Shaved|Salon][getSlave($AS).hStyle = "shaved",getSlave($AS).hLength = 0,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Trimmed short|Salon][getSlave($AS).hStyle = "trimmed",getSlave($AS).hLength = 10,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Buzzcut|Salon][getSlave($AS).hStyle = "buzzcut",getSlave($AS).hLength = 1,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<</if>>
-		</div>
-
-		<div class="choices">
-			Cut or lengthen $his hair:
-			<<if getSlave($AS).hLength > 5>>
-				[[Very short|Salon][getSlave($AS).hLength = 5,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<</if>>
-			<<if getSlave($AS).hLength > 10>>
-				| [[Short|Salon][getSlave($AS).hLength = 10,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<</if>>
-			<<if getSlave($AS).hLength > 30>>
-				| [[Shoulder length|Salon][getSlave($AS).hLength = 30,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<</if>>
-			<<if getSlave($AS).hLength > 60>>
-				| [[Long|Salon][getSlave($AS).hLength = 60,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<</if>>
-			<<if getSlave($AS).hLength > 100>>
-				| [[Very long|Salon][getSlave($AS).hLength = 100,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<</if>>
-			<<if getSlave($AS).hLength == 1>>
-				| [[Apply hair growth stimulating treatment|Salon][getSlave($AS).hLength = 1,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<<elseif getSlave($AS).hLength < 150>>
-				| [[Apply extensions|Salon][getSlave($AS).hLength += 10,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			<</if>>
-				| Custom length: <<textbox "_newHLength" _oldHLength "Salon">>
-			<<if $showInches == 1>>
-				cm (<<= cmToInchString(getSlave($AS).hLength)>>)
-			<<elseif $showInches == 2>>
-				inches
-			<</if>>
-			[[Apply|Salon][cashX(forceNeg($modCost), "slaveMod", getSlave($AS)), getSlave($AS).hLength = (Number(_newHLength) || getSlave($AS).hLength)]]
-		</div>
-
-		<div class="choices">
-			Have $his hair carefully maintained at its current length:
-			<<if getSlave($AS).haircuts == 1>>
-				[[Cease maintenance|Salon][getSlave($AS).haircuts = 0]]
-			<<else>>
-				[[Begin maintenance|Salon][getSlave($AS).haircuts = 1]]
-			<</if>>
-		</div>
-	<<else>>
-		<<if getSlave($AS).hStyle == "bald">>
-			$He is completely bald.
-		<<else>>
-			$His current wig is <<= getSlave($AS).hColor>>.
-			<<if getSlave($AS).hStyle != "bald">>
-				[[Remove wig|Salon][getSlave($AS).hStyle = "bald",getSlave($AS).hLength = 0,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]] or <span class="note">choose a new one:</span>
-			<<else>>
-				<span class="note">Choose a wig color:</span>
-			<</if>>
-
-			<div class="choices">
-				Colors:
-					[[Auburn|Salon][$primaryHairColor = "auburn"]]
-					| [[Black|Salon][$primaryHairColor = "black"]]
-					| [[Blazing Red|Salon][$primaryHairColor = "blazing red"]]
-					| [[Blonde|Salon][$primaryHairColor = "blonde"]]
-					| [[Blue-Violet|Salon][$primaryHairColor = "blue-violet"]]
-					| [[Blue|Salon][$primaryHairColor = "blue"]]
-					| [[Brown|Salon][$primaryHairColor = "brown"]]
-					| [[Burgundy|Salon][$primaryHairColor = "burgundy"]]
-					| [[Chestnut|Salon][$primaryHairColor = "chestnut"]]
-					| [[Chocolate|Salon][$primaryHairColor = "chocolate brown"]]
-					| [[Copper|Salon][$primaryHairColor = "copper"]]
-					| [[Dark Blue|Salon][$primaryHairColor = "dark blue"]]
-					| [[Dark Brown|Salon][$primaryHairColor = "dark brown"]]
-					| [[Dark Orchid|Salon][$primaryHairColor = "dark orchid"]]
-					| [[Deep Red|Salon][$primaryHairColor = "deep red"]]
-					| [[Ginger|Salon][$primaryHairColor = "ginger"]]
-					| [[Golden|Salon][$primaryHairColor = "golden"]]
-					| [[Green-yellow|Salon][$primaryHairColor = "green-yellow"]]
-					| [[Green|Salon][$primaryHairColor = "green"]]
-					| [[Grey|Salon][$primaryHairColor = "grey"]]
-					| [[Hazel|Salon][$primaryHairColor = "hazel"]]
-					| [[Jet Black|Salon][$primaryHairColor = "jet black"]]
-					| [[Neon Blue|Salon][$primaryHairColor = "neon blue"]]
-					| [[Neon Green|Salon][$primaryHairColor = "neon green"]]
-					| [[Neon Pink|Salon][$primaryHairColor = "neon pink"]]
-					| [[Pink|Salon][$primaryHairColor = "pink"]]
-					| [[Platinum Blonde|Salon][$primaryHairColor = "platinum blonde"]]
-					| [[Purple|Salon][$primaryHairColor = "purple"]]
-					| [[Red|Salon][$primaryHairColor = "red"]]
-					| [[Sea Green|Salon][$primaryHairColor = "sea green"]]
-					| [[Silver|Salon][$primaryHairColor = "silver"]]
-					| [[Strawberry-Blonde|Salon][$primaryHairColor = "strawberry-blonde"]]
-					| [[White|Salon][$primaryHairColor = "white"]]
-			</div>
-
-			<div class="choices">
-				Highlights:
-					[[None|Salon][$secondaryHairColor = ""]]
-					| [[Black|Salon][$secondaryHairColor = " with black highlights"]]
-					| [[Blazing Red|Salon][$secondaryHairColor = " with blazing red highlights"]]
-					| [[Blonde|Salon][$secondaryHairColor = " with blonde highlights"]]
-					| [[Grey|Salon][$secondaryHairColor = " with grey highlights"]]
-					| [[Neon Blue|Salon][$secondaryHairColor = " with neon blue highlights"]]
-					| [[Neon Green|Salon][$secondaryHairColor = " with neon green highlights"]]
-					| [[Neon Pink|Salon][$secondaryHairColor = " with neon pink highlights"]]
-					| [[Rainbow|Salon][$secondaryHairColor = " with rainbow highlights"]]
-					| [[Silver|Salon][$secondaryHairColor = " with silver highlights"]]
-					| [[White|Salon][$secondaryHairColor = " with white highlights"]]
-			</div>
-
-			<<if $primaryHairColor != 0>>
-				<div class="choices">
-					[[Change|Salon][getSlave($AS).hColor = ($primaryHairColor + $secondaryHairColor),cashX(forceNeg($modCost), "slaveMod", getSlave($AS)), $primaryHairColor = 0, $secondaryHairColor = ""]] $his wig color to $primaryHairColor $secondaryHairColor
-				</div>
-			<</if>>
-		<</if>>
+<p id="salonHair"></p>
+<script>
+	App.Medicine.Salon.hair(getSlave(V.AS));
+</script>
 
-		<div>
-			<<if getSlave($AS).hStyle != "bald">>
-				$His <<= getSlave($AS).hStyle>> wig is <<= lengthToEitherUnit(getSlave($AS).hLength)>> long.
-				<span class="note">General hairstyles will conform to hair length and clothing choices.</span>
-
-				<<if getSlave($AS).hLength == 0>><<set getSlave($AS).hLength = 10>><</if>>
-
-				<div class="choices">
-					Set wig length to:
-					<<if getSlave($AS).hLength != 10>>[[lengthToEitherUnit(10)|Salon][getSlave($AS).hLength = 10,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]<</if>>
-					<<if getSlave($AS).hLength != 30>>[[lengthToEitherUnit(30)|Salon][getSlave($AS).hLength = 30,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]<</if>>
-					<<if getSlave($AS).hLength != 60>>[[lengthToEitherUnit(60)|Salon][getSlave($AS).hLength = 60,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]<</if>>
-					<<if getSlave($AS).hLength != 90>>[[lengthToEitherUnit(90)|Salon][getSlave($AS).hLength = 90,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]<</if>>
-					<<if getSlave($AS).hLength != 120>>[[lengthToEitherUnit(120)|Salon][getSlave($AS).hLength = 120,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]<</if>>
-					<<if getSlave($AS).hLength != 150>>[[lengthToEitherUnit(150)|Salon][getSlave($AS).hLength = 150,cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]<</if>>
-				</div>
-			<<else>>
-				$He is not wearing a wig.
-			<</if>>
-			<div class="choices">
-				<<if getSlave($AS).hStyle != "bald">>
-					Set wig style:
-				<<else>>
-					Give $him a wig:
-				<</if>>
-				[[Afro|Salon][getSlave($AS).hStyle = "afro",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Braided|Salon][getSlave($AS).hStyle = "braided",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Cornrows|Salon][getSlave($AS).hStyle = "cornrows",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Curled|Salon][getSlave($AS).hStyle = "curled",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Dreadlocks|Salon][getSlave($AS).hStyle = "dreadlocks",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Eary|Salon][getSlave($AS).hStyle = "eary",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In a bun|Salon][getSlave($AS).hStyle = "bun",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In a messy bun|Salon][getSlave($AS).hStyle = "messy bun",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In a ponytail|Salon][getSlave($AS).hStyle = "ponytail",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[In tails|Salon][getSlave($AS).hStyle = "tails",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Luxurious|Salon][getSlave($AS).hStyle = "luxurious",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Messy|Salon][getSlave($AS).hStyle = "messy",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Neat|Salon][getSlave($AS).hStyle = "neat",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Permed|Salon][getSlave($AS).hStyle = "permed",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Shaved sides|Salon][getSlave($AS).hStyle = "strip",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-				| [[Up|Salon][getSlave($AS).hStyle = "up",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			</div>
-		</div>
-	<</if>>
-</div>
 /* MAKEUP */
 <h3>Makeup</h3>
 
@@ -666,7 +412,7 @@
 			| [[Dark Blue|Salon][getSlave($AS).eyebrowHColor = "dark blue",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Dark Brown|Salon][getSlave($AS).eyebrowHColor = "dark brown",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Dark Orchid|Salon][getSlave($AS).eyebrowHColor = "dark orchid",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			| [[Deep Red|Salon][$primaryHairColor = "deep red"]]
+			| [[Deep Red|Salon][getSlave($AS).eyebrowHColor = "deep red",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Ginger|Salon][getSlave($AS).eyebrowHColor = "ginger",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Golden|Salon][getSlave($AS).eyebrowHColor = "golden",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Green-yellow|Salon][getSlave($AS).eyebrowHColor = "green-yellow",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
@@ -757,7 +503,7 @@
 			| [[Dark Blue|Salon][getSlave($AS).pubicHColor = "dark blue",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Dark Brown|Salon][getSlave($AS).pubicHColor = "dark brown",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Dark Orchid|Salon][getSlave($AS).pubicHColor = "dark orchid",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			| [[Deep Red|Salon][$primaryHairColor = "deep red"]]
+			| [[Deep Red|Salon][getSlave($AS).pubicHColor = "deep red",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Ginger|Salon][getSlave($AS).pubicHColor = "ginger",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Golden|Salon][getSlave($AS).pubicHColor = "golden",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Green-yellow|Salon][getSlave($AS).pubicHColor = "green-yellow",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
@@ -831,7 +577,7 @@
 			| [[Dark Blue|Salon][getSlave($AS).underArmHColor = "dark blue",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Dark Brown|Salon][getSlave($AS).underArmHColor = "dark brown",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Dark Orchid|Salon][getSlave($AS).underArmHColor = "dark orchid",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
-			| [[Deep Red|Salon][$primaryHairColor = "deep red"]]
+			| [[Deep Red|Salon][getSlave($AS).underArmHColor = "deep red",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Ginger|Salon][getSlave($AS).underArmHColor = "ginger",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Golden|Salon][getSlave($AS).underArmHColor = "golden",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]
 			| [[Green-yellow|Salon][getSlave($AS).underArmHColor = "green-yellow",cashX(forceNeg($modCost), "slaveMod", getSlave($AS))]]