diff --git a/src/markets/JobFulfillmentCenterOrder.js b/src/markets/JobFulfillmentCenterOrder.js
new file mode 100644
index 0000000000000000000000000000000000000000..30bbe33aece91b5d99308d918ec8fe765a70710f
--- /dev/null
+++ b/src/markets/JobFulfillmentCenterOrder.js
@@ -0,0 +1,110 @@
+App.Markets.JobFulfillmentCenterOrder = function() {
+	V.encyclopedia = "Kidnapped Slaves";
+	let r = [];
+	let linkArray = [];
+	const el = document.createElement("p");
+	el.id = "job-fulfillment-center-order";
+	el.append(JobFulfillmentCenterOrder());
+	return el;
+
+	function JobFulfillmentCenterOrder() {
+		const el = new DocumentFragment();
+		let span = document.createElement("span");
+		const {heA} = getPronouns(assistant.pronouns().main).appendSuffix('A');
+
+		if (V.JFC.order === 0) {
+			r.push(`You work up a new slave order for posting where slave merchants can work to fulfill it.`);
+		}
+		if (V.JFC.order === 1) {
+			r.push(`You review your posted slave order for a ''${V.JFC.role}''.`);
+		}
+		if (V.assistant.personality === 1) {
+			r.push(`As you work, ${V.assistant.name} makes lewd comments about what ${heA} looks forward to doing to this new slave.`);
+		}
+		el.append(r.join(" "));
+
+		if (V.JFC.order === 0) {
+			const security = [
+				{title: "Bodyguard"},
+				{title: "Wardeness"},
+			];
+			const management = [
+				{title: "Headgirl"},
+				{title: "Teacher"},
+				{title: "Nurse"},
+				{title: "Attendant (normal)", value: "Attendant"},
+				{title: "Attendant (motherly)", value: "Motherly Attendant"},
+				{title: "Matron"},
+				{title: "Stewardess"},
+				{title: "Milkmaid"},
+				{title: "Farmer"},
+			];
+			const entertainment = [
+				{title: "DJ"},
+				{title: "Madam"},
+				{title: "Concubine"},
+
+			];
+			linkArray.push(
+				App.UI.DOM.link(
+					"Security",
+					() => {
+						jobSelection(security);
+					}
+				)
+			);
+			linkArray.push(
+				App.UI.DOM.link(
+					"Management",
+					() => {
+						jobSelection(management);
+					}
+				)
+			);
+			linkArray.push(
+				App.UI.DOM.link(
+					"Entertainment",
+					() => {
+						jobSelection(entertainment);
+					}
+				)
+			);
+			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray));
+			span.id = "job-type";
+			el.append(span);
+		} else {
+			App.UI.DOM.appendNewElement("div", el,
+				App.UI.DOM.link(
+					"Withdraw slave order",
+					() => {
+						V.JFC.order = 0;
+						V.JFC.role = "";
+						refresh();
+					}
+				)
+			);
+		}
+		return el;
+
+		function jobSelection(choices) {
+			const el = new DocumentFragment();
+			for (const choice of choices) {
+				App.UI.DOM.appendNewElement("div", el,
+					App.UI.DOM.link(
+						choice.title,
+						() => {
+							V.JFC.order = 1;
+							V.JFC.role = choice.value || choice.title;
+							refresh();
+						}
+					)
+				);
+			}
+			return jQuery("#job-type").empty().append(el);
+		}
+
+		function refresh() {
+			jQuery("#job-fulfillment-center-order").empty().append(JobFulfillmentCenterOrder());
+		}
+	}
+};
diff --git a/src/markets/JobFulfillmentCenterOrder.tw b/src/markets/JobFulfillmentCenterOrder.tw
deleted file mode 100644
index afa2511936397067d6d0b3527700161f9eeaad18..0000000000000000000000000000000000000000
--- a/src/markets/JobFulfillmentCenterOrder.tw
+++ /dev/null
@@ -1,49 +0,0 @@
-:: JobFulfillmentCenterOrder [nobr]
-
-<<set $nextButton = "Back", $nextLink = "Buy Slaves", $returnTo = "Buy Slaves", $encyclopedia = "Kidnapped Slaves">>
-
-<<setAssistantPronouns>>
-
-<<if $JFC.order == 0>>You work up a new slave order for posting where slave merchants can work to fulfill it.<</if>> <<if $JFC.order == 1>>You review your posted slave order for a ''$JFC.role''.<</if>> <<if $assistant.personality == 1>>As you work, $assistant.name makes lewd comments about what _heA looks forward to doing to this new slave.<</if>>
-
-<<if $JFC.order == 0>>
-	<span id="JobType">
-	<br><br>
-		<<link "Security">>
-			<<replace "#JobType">>
-					<br>
-					<br>[[Bodyguard|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Bodyguard"]]
-					<br>[[Wardeness|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Wardeness"]]
-					<br>[[Return|JobFulfillmentCenterOrder]]
-			<</replace>>
-		<</link>>
-
-		<br><<link "Management">>
-			<<replace "#JobType">>
-				<br>
-				<br>[[Headgirl|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Headgirl"]]
-				<br>[[Teacher|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Teacher"]]
-				<br>[[Nurse|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Nurse"]]
-				<br>[[Attendant (normal)|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Attendant"]] | [[Attendant (motherly)|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Motherly Attendant"]]
-				<br>[[Matron|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Matron"]]
-				<br>[[Stewardess|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Stewardess"]]
-				<br>[[Milkmaid|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Milkmaid"]]
-				<br>[[Farmer|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Farmer"]]
-				<br>[[Return|JobFulfillmentCenterOrder]]
-			<</replace>>
-		<</link>>
-
-		<br><<link "Entertainment">>
-			<<replace "#JobType">>
-				<br>
-				<br>[[DJ|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "DJ"]]
-				<br>[[Madam|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Madam"]]
-				<br>[[Concubine|JobFulfillmentCenterOrder][$JFC.order = 1, $JFC.role = "Concubine"]]
-				<br>[[Return|JobFulfillmentCenterOrder]]
-			<</replace>>
-		<</link>>
-	</span>
-<<else>>
-	<br>
-	<br>[[Withdraw slave order|JobFulfillmentCenterOrder][$JFC.order = 0, $JFC.role = ""]]
-<</if>>
diff --git a/src/markets/theMarket/marketData.js b/src/markets/theMarket/marketData.js
index db5a8909350cd1fc97fcf83e402af787e7d59866..2e769b4cabb16095356595e669ae587140a4a4f2 100644
--- a/src/markets/theMarket/marketData.js
+++ b/src/markets/theMarket/marketData.js
@@ -5,7 +5,6 @@
 /**
  * @typedef {object} market
  * @property {string} title
- * @property {string} [passage]
  * @property {string} [marketType]
  * @property {string} [note]
  * @property {string} [sale]
@@ -18,7 +17,6 @@ App.Data.Markets = {
 	low: [
 		{
 			title: "Corporate Market",
-			passage: `Corporate Market`,
 			marketType: "corporate",
 			get note() { return V.corp.Market === 1 ? `Slaves from your corporation purchased at a discounted rate.` : `Slaves from your corporation`; },
 			sale: "",
@@ -33,7 +31,7 @@ App.Data.Markets = {
 		},
 		{
 			title: "Order a custom husk slave from the Flesh Heap",
-			passage: `Husk Slave`,
+			marketType: `Husk Slave`,
 			note: `Will need to be used on arrival.`,
 			bulkAvailable: false,
 			get requirements() { return (V.bodyswapAnnounced === 1); }
@@ -88,7 +86,7 @@ App.Data.Markets = {
 		},
 		{
 			title: "Prisoner Sale",
-			passage: `Criminal Market`,
+			marketType: `Criminal Market`,
 			get note() {
 				switch (V.prisonCircuit[V.prisonCircuitIndex]) {
 					case "low tier criminals":
@@ -124,78 +122,67 @@ App.Data.Markets = {
 		{
 			title: "The Slavegirl School",
 			marketType: "TSS",
-			passage: "The Slavegirl School",
 			note: "Straightforward slaves with good training.",
 			get requirements() { return (V.seeDicks !== 100); }
 		},
 		{
 			title: "The Utopian Orphanage",
 			marketType: "TUO",
-			passage: "The Utopian Orphanage",
 			note: "Intelligent, unspoiled slaves just past their majority.",
 			get requirements() { return (V.seeDicks !== 100); }
 		},
 		{
 			title: "Growth Research Institute",
 			marketType: "GRI",
-			passage: "Growth Research Institute",
 			note: "Poorly trained slaves with huge assets.",
 			get requirements() { return (V.seeDicks !== 100); }
 		},
 		{
 			title: "St. Claver Preparatory",
 			marketType: "SCP",
-			passage: "St. Claver Preparatory",
 			note: "Slaves with basic training and solid implants.",
 			get requirements() { return (V.seeDicks !== 100); }
 		},
 		{
 			title: "The Cattle Ranch",
 			marketType: "TCR",
-			passage: "The Cattle Ranch",
 			note: "Mentally conditioned free-range cowgirls.",
 			get requirements() { return (V.seeDicks !== 100); }
 		},
 		{
 			title: "The Hippolyta Academy",
 			marketType: "HA",
-			passage: "The Hippolyta Academy",
 			note: "High quality slaves of powerful physique and refined skills.",
 			get requirements() { return (V.seeDicks !== 100); }
 		},
 		{
 			title: "L'École des Enculées",
 			marketType: "LDE",
-			passage: "L'École des Enculées",
 			note: "Slaves optimized and trained for anal.",
 			get requirements() { return (V.seeDicks !== 0); }
 		},
 		{
 			title: "The Gymnasium-Academy",
 			marketType: "TGA",
-			passage: "The Gymnasium-Academy",
 			note: "Well trained slaves with dicks.",
 			get requirements() { return (V.seeDicks !== 0); }
 		},
 		{
 			title: "The Futanari Sisters",
 			marketType: "TFS",
-			passage: "The Futanari Sisters",
 			note: "Highly skilled, highly feminine hermaphrodites.",
 			get requirements() { return (V.seeDicks !== 0); }
 		},
 		{
 			title: "Nueva Universidad de Libertad",
 			marketType: "NUL",
-			passage: "Nueva Universidad de Libertad",
 			note: "Androgynous slaves lacking genitalia.",
 		},
 	],
 	high: [
 		{
 			title: "Take in a shelter slave",
-			passage: `Slave Shelter`,
-			marketType: "",
+			marketType: "Slave Shelter",
 			note: "Presents charity cases for a nominal fee.",
 			bulkAvailable: false,
 			get requirements() {
@@ -223,40 +210,35 @@ App.Data.Markets = {
 		},
 		{
 			title: "Place a special order",
-			passage: `Custom Slave`,
-			marketType: "",
+			marketType: "Custom Slave",
 			note: "Customizable but very expensive.",
 			bulkAvailable: false,
 			get requirements() { return (V.rep > 10000) ? true : `You are not reputable enough to order custom slaves.`; }
 		},
 		{
 			title: "Place a fulfillment order",
-			passage: `JobFulfillmentCenterOrder`,
-			marketType: "",
+			marketType: "JobFulfillmentCenterOrder",
 			note: "Fills leaderships roles for a price.",
 			bulkAvailable: false,
 			get requirements() { return (V.rep > 10000); }
 		},
 		{
 			title: "Attend an auction of a prestigious slave",
-			passage: `Prestigious Slave`,
-			marketType: "",
+			marketType: "Prestigious Slave",
 			note: "Variable and expensive.",
 			bulkAvailable: false,
 			get requirements() { return (V.rep > 12000) ? true : `You are not reputable enough to bid on prestigious slaves.`; }
 		},
 		{
 			title: "Attend an auction of other Elite's stock",
-			passage: `Elite Slave`,
-			marketType: "",
+			marketType: "Elite Slave",
 			note: "Limited and very expensive.",
 			bulkAvailable: false,
 			get requirements() { return (V.propOutcome === 1); }
 		},
 		{
 			title: "Acquire other slaveowners' stock",
-			passage: `Special Slave`,
-			marketType: "",
+			marketType: "Special Slave",
 			note: "Variable and expensive",
 			bulkAvailable: false,
 			get requirements() { return (V.rep > 14000) ? true : `You are not reputable enough to acquire other slaveowners' stock.`; }