diff --git a/src/facilities/salon/salonPassage.js b/src/facilities/salon/salonPassage.js
index 5c8b678c639a7e6299ccfce1986a5ff7bad6794b..8165ec052c56174b093af87eb93080589547369d 100644
--- a/src/facilities/salon/salonPassage.js
+++ b/src/facilities/salon/salonPassage.js
@@ -30,7 +30,9 @@ App.UI.salon = function(slave, cheat = false) {
 		if (slave.horn !== "none") {
 			el.append(horns());
 		}
+		el.append(hair());
 		el.append(makeup());
+		el.append(skin());
 		return el;
 	}
 
@@ -143,24 +145,64 @@ App.UI.salon = function(slave, cheat = false) {
 		return el;
 	}
 
+	function hair() {
+		const el = new DocumentFragment();
+		App.UI.DOM.appendNewElement("h2", el, "Hair");
+
+		el.append(App.Medicine.Salon.hair(slave, {cheat: cheat}));
+		return el;
+	}
+
 	function skin() {
 		const el = new DocumentFragment();
 		App.UI.DOM.appendNewElement("h2", el, "Skin");
 		const options = new App.UI.OptionsGroup();
+		let comment = [];
 
-		options.addOption(App.Desc.makeup(slave), "makeup", slave)
-			.addValue("Nice", 1, billMod)
-			.addValue("Gorgeous", 2, billMod)
-			.addValue("Slutty", 4, billMod)
-			.addValue("Color-coordinate with hair", 3, billMod);
+		let option = options.addOption(`${His} skin is ${slave.skin}.`, "skin", slave);
+		if (App.Data.misc.dyedSkins.includes(slave.skin)) {
+			option.addValue("Remove coloring", slave.origSkin, billMod);
+		} else if (((slave.skin === "sun tanned") || (slave.skin === "spray tanned"))) {
+			option.addValue("Remove tanning", slave.origSkin, billMod);
+		}
 
-		options.addOption("", "makeup", slave)
-			.addValue("Neon", 5, billMod)
-			.addValue("Neon, color-coordinate with hair", 6, billMod);
+		if (!App.Data.misc.dyedSkins.includes(slave.skin)) {
+			if (slave.skin === "sun tanned" || slave.skin === "spray tanned") {
+				comment.push(`${His} skin tanning must be removed before any advanced procedure to change ${his} skin color.`);
+			} else {
+				if (skinToneLevel(slave.skin) > 1) {
+					option.addValue("Bleach", changeSkinTone(slave.skin, -2), billMod);
+				}
+				if (skinToneLevel(slave.skin) > 8) {
+					option.addValue("Lighten", changeSkinTone(slave.skin, -1), billMod);
+				}
+				if (skinToneLevel(slave.skin) < 18) {
+					option.addValue("Darken", changeSkinTone(slave.skin, 1), billMod);
+				}
+				if (skinToneLevel(slave.skin) < 25) {
+					option.addValue("Blacken", changeSkinTone(slave.skin, 2), billMod);
+				}
+			}
+			if (slave.skin !== "sun tanned") {
+				if (skinToneLevel(slave.skin) < 6) {
+					comment.push(`${His} skin is so light in color that any attempt at natural tanning is more likely to damage ${his} skin.`);
+				} else if ((skinToneLevel(slave.skin) > 20)) {
+					comment.push(`${His} skin is so dark in color that any attempt at natural tanning is not likely to appear on ${his} skin.`);
+				} else {
+					option.addValue("Sun tan", "sun tanned", billMod);
+				}
+			}
+			if (slave.skin !== "spray tanned") {
+				option.addValue("Spray tan", "sun tanned", billMod)
+			}
+			option.addComment(comment.join(" "));
+		}
 
-		options.addOption("", "makeup", slave)
-			.addValue("Metallic", 7, billMod)
-			.addValue("Metallic, color-coordinate with hair", 8, billMod);
+		option = options.addOption(`Dye or paint`, "skin", slave);
+		for (const dye of App.Data.misc.dyedSkins) {
+			option.addValue(capFirstChar(dye), dye, billMod);
+		}
+		option.pulldown();
 
 		el.append(options.render());
 
diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js
index 03ce426239d71eb0f92e498c642749506d27e6be..82a082bc044ae6f1b07a8328607161c7eecd78e5 100644
--- a/src/js/rulesAssistantOptions.js
+++ b/src/js/rulesAssistantOptions.js
@@ -4022,13 +4022,7 @@ globalThis.rulesAssistantOptions = (function() {
 				["pure black"],
 				["sun tanned"],
 				["spray tanned"],
-				["dyed red"],
-				["dyed green"],
-				["dyed blue"],
-				["dyed pink"],
-				["dyed gray"],
-				["tiger striped"],
-				["camouflage patterned"],
+				...App.Data.misc.dyedSkins
 			];
 			super("Dye or tan skin", items);
 			this.setValue(current_rule.set.skinColor);
diff --git a/src/js/salon.js b/src/js/salon.js
index 92a5bb4b770a6e03a90638a745389ea3c0635d06..04e21f62dd86d985cdc01560d2e7a31783211afb 100644
--- a/src/js/salon.js
+++ b/src/js/salon.js
@@ -335,30 +335,37 @@ App.Medicine.Salon.ears = function(slave, {primaryEarColor = 0, secondaryEarColo
  * @param {number|string} [params.primaryHairColor]
  * @param {string} [params.secondaryHairColor]
  * @param {Boolean} [params.cheat=false]
- * @returns {JQuery<HTMLElement>}
+ * @returns {HTMLElement}
  */
 App.Medicine.Salon.hair = function(slave, {primaryHairColor = 0, secondaryHairColor = "", cheat = false} = {}) {
-	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);
+	const div = document.createElement("div");
+	div.id = "salon-hair";
+	div.append(contents());
 
-	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. `);
+	return div;
+
+	function contents() {
+		const frag = new DocumentFragment();
+		if (slave.bald !== 1) {
+			frag.append(hairDye());
+			frag.append(hairStyle());
+			frag.append(hairLength());
+			frag.append(hairMaint());
 		} else {
-			frag.append(wigDye());
+			// Bald
+			if (slave.hStyle === "bald") {
+				frag.append(`${He} is completely bald. `);
+			} else {
+				frag.append(wigDye());
+			}
+			frag.append(wigStyle());
+			frag.append(wigLength());
 		}
-		frag.append(wigStyle());
-		frag.append(wigLength());
+		return frag;
 	}
-	return jQuery("#salon-hair").empty().append(frag);
 
 	function hairDye() {
 		const frag = new DocumentFragment();