diff --git a/src/gui/css/options.css b/src/gui/css/options.css
index 2403a0cd3c01f91b700e7734913b6893ef6ec37c..7f559889c95a4eba4eb41ffd6b237309e385e410 100644
--- a/src/gui/css/options.css
+++ b/src/gui/css/options.css
@@ -19,12 +19,10 @@ div.options-group span.comment {
 div.options-group button {
     color: var(--link-color);
     background-color: var(--button-color);
-    border: solid 2px var(--button-border-color);
-    margin: 4px 0;
-}
-
-div.options-group button:not(:first-child) {
-    border-left: none; /* Prevent double borders */
+    border: none; /* outline instead of border */
+    /* left & right outline overlap each other so we don't have  a double border */
+    outline: solid 2px var(--button-border-color);
+    margin: 6px 0 6px 2px;
 }
 
 div.options-group button:hover {
diff --git a/src/gui/options.js b/src/gui/options.js
index 21e8c88d85c78f57ef48659431de68dc48227635..8ad74d00e471f85d43db185eeaf286a511a4e479 100644
--- a/src/gui/options.js
+++ b/src/gui/options.js
@@ -82,6 +82,13 @@ App.UI.OptionsGroup = (function() {
 				return this;
 			}
 
+			/**
+			 * @param {Function} callback gets executed on every button click. Selected value is given as argument.
+			 */
+			addCallback(callback) {
+				this.callback = callback;
+			}
+
 			/**
 			 * Adds a button that executes the callback when clicked AND reloads the passage
 			 *
@@ -211,6 +218,9 @@ App.UI.OptionsGroup = (function() {
 							}
 							button.onclick = () => {
 								option.object[option.property] = value.value;
+								if (option.callback) {
+									option.callback(value.value);
+								}
 								reload();
 							};
 						}
@@ -220,6 +230,9 @@ App.UI.OptionsGroup = (function() {
 						const isNumber = typeof currentValue === "number";
 						const textbox = App.UI.DOM.makeTextBox(currentValue, input => {
 							option.object[option.property] = input;
+							if (option.callback) {
+								option.callback(input);
+							}
 							reload();
 						}, isNumber);
 						if (isNumber) {
diff --git a/src/js/slaveSummaryWidgets.js b/src/js/slaveSummaryWidgets.js
index e3e822c0e61d99d99578f238d0bda03727a86ace..a11f595f763518db984468878a8c21fb798d626f 100644
--- a/src/js/slaveSummaryWidgets.js
+++ b/src/js/slaveSummaryWidgets.js
@@ -949,9 +949,10 @@ App.UI.SlaveSummary = function() {
 		return res;
 	}
 
-	function displayOptionsFragment() {
-		const res = document.createDocumentFragment();
-
+	/**
+	 * @param {App.UI.OptionsGroup} optionsGroup
+	 */
+	function addOptions(optionsGroup) {
 		// SAH is "Summarized, Abbreviated, Hidden"
 		const SAHOptions = {
 			"Summarized": 2,
@@ -960,12 +961,11 @@ App.UI.SlaveSummary = function() {
 		};
 
 		function appendOption(name, desc, options) {
-			res.append(App.UI.DOM.Widgets.optionSelector((value) => {
-				V.UI.slaveSummary.abbreviation[name] = value;
-				initDelegates();
-				Engine.play(passage());
-			},
-			options, V.UI.slaveSummary.abbreviation[name], desc));
+			const option = optionsGroup.addOption(desc, name, V.UI.slaveSummary.abbreviation);
+			option.addCallback(() => initDelegates());
+			for (const key in options) {
+				option.addValue(key, options[key]);
+			}
 		}
 
 		function appendSAHOption(name, desc) {
@@ -996,8 +996,6 @@ App.UI.SlaveSummary = function() {
 			"Summarized": 2,
 			"Hidden": 0
 		});
-
-		return res;
 	}
 
 	return {
@@ -1005,6 +1003,6 @@ App.UI.SlaveSummary = function() {
 		settingsChanged: settingsChanged,
 		societyChanged: societyChanged,
 		render: render,
-		displayOptionsFragment: displayOptionsFragment
+		addOptions: addOptions
 	};
 }();
diff --git a/src/uncategorized/descriptionOptions.tw b/src/uncategorized/descriptionOptions.tw
index d711901c483e9044c5c9ec73ff7753be2a7cdbb4..d25696f3231deec4812514faaf6c37b67aa79e8b 100644
--- a/src/uncategorized/descriptionOptions.tw
+++ b/src/uncategorized/descriptionOptions.tw
@@ -1,13 +1,5 @@
 :: Description Options [nobr]
 
-<style>
-.subHeading {
-	width: 85%;
-	text-align: center;
-	margin-top: 1.5em;
-}
-</style>
-
 <<set $nextButton = "Back">>
 <<if $storedLink !== "Slave Interact">>
 	<<if lastVisited("Slave Interact") === 1>>
@@ -18,109 +10,65 @@
 <</if>>
 <<set $nextLink = $storedLink>>
 
+<h1>Description Options</h1>
+
 //These options will affect both the long form description of each slave and the miniscenes available from the main menu.//
 
-<br>
-<<options $surnameOrder>>
-	<<option 0 "Allow nationality name order">>
-	Order names ''based on country of origin''.
-	<<option 1 "Force name surname">>
-	Names will always be ''Name Surname''.
-	<<option 2 "Force surname name">>
-	Names will always be ''Surname Name''.
-<</options>>
-
-<br>
-<<options $seeRace>>
-	<<option 0 "Disable most mentions of race">>
-		Ethnicity will ''almost never'' be mentioned.
-	<<option 1 "Enable mentions of race">>
-		Ethnicity will ''occasionally'' be mentioned.
-<</options>>
-<br>
-<<options $seeNationality>>
-	<<option 0 "Disable most mentions of nationality">>
-		Nationality will ''almost never'' be mentioned.
-	<<option 1 "Enable mentions of nationality">>
-		Nationality will ''occasionally'' be mentioned.
-<</options>>
-
-<br>
-<<options $showImplantEffects>>
-	The effects of implants are
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-
-<<options $showClothing>>
-	Clothing is mostly
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-<br>
-<<options $showAgeDetail>>
-	Detailed slave age information is
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-<br>
-<<options $showHeightCMs>>
-	Approximate height is
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-
-<<options $showBodyMods>>
-	Cosmetic body mods are
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-
-<br>
-<<options $showSexualHistory>>
-	Sexual histories are
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-
-<<options $showScores>>
-	Attractiveness and Sexual scores are
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-
-<br>
-<<options $showBoobCCs>>
-	Volume, in CCs, of breasts is
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-<<options $showInches>>
-	Height and length units are in
-	<<option 0 "Metric">>
-	<<option 1 "Both">>
-	<<option 2 "Imperial">>
-<</options>>
-
-
-<div class="subHeading">
+<<set _options = new App.UI.OptionsGroup()>>
+
+<<run _options.addOption("", "surnameOrder")
+.addValue("Allow nationality name order", 0).customDescription("Order names ''based on country of origin''.")
+.addValue("Force name surname", 1).customDescription("Names will always be ''Name Surname''.")
+.addValue("Force surname name", 2).customDescription("Names will always be ''Surname Name''.")>>
+
+<<run _options.addOption("", "seeRace")
+.addValue("Disable most mentions of race", 0).off().customDescription("Ethnicity will ''almost never'' be mentioned.")
+.addValue("Enable mentions of race", 1).on().customDescription("Ethnicity will ''occasionally'' be mentioned.")>>
+
+<<run _options.addOption("", "seeNationality")
+.addValue("Disable most mentions of nationality", 0).off().customDescription("Nationality will ''almost never'' be mentioned.")
+.addValue("Enable mentions of nationality", 1).on().customDescription("Nationality will ''occasionally'' be mentioned.")>>
+
+<<run _options.addOption("The effects of implants are", "showImplantEffects")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Clothing is mostly", "showClothing")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Detailed slave age information is", "showAgeDetail")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Approximate height is", "showHeightCMs")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Cosmetic body mods are", "showBodyMods")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Sexual histories are", "showSexualHistory")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Attractiveness and Sexual scores are", "showScores")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Volume, in CCs, of breasts is", "showBoobCCs")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Height and length units are in", "showInches")
+.addValueList([["Metric", 0], ["Both", 1], ["Imperial", 2]])>>
+
+
 <<if $seeDicks > 0>> <br>
-	<<options $showDickCMs>>
-		Approximate sizes of dicks and balls are
-		<<option 1 "Shown">>
-		<<option 0 "Hidden">>
-	<</options>>
+	<<run _options.addOption("Approximate sizes of dicks and balls are", "showDickCMs")
+	.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
 <</if>>
-</div>
-
-<div class="subHeading">
-<<if $showNumbers == 1>>Only numbers @@.cyan;UP TO $showNumbersMax@@<<else>>Numbers<</if>> are displayed as
-<<if $showNumbers == 1>>
-	words.
-	<<textbox "$showNumbersMax" $showNumbersMax>> //[[Words|Description Options][$showNumbers = 0]]// | //[[Integers|Description Options][$showNumbers = 2]]//
-<<elseif $showNumbers == 2>>
-	@@.yellow;INTEGERS.@@ //[[Words|Description Options][$showNumbers = 0]]// | //[[Both|Description Options][$showNumbers = 1, $showNumbersMax = 20]]//
-<<else>>
-	@@.yellow;WORDS.@@ //[[Integers|Description Options][$showNumbers = 2]]// | //[[Both|Description Options][$showNumbers = 1, $showNumbersMax = 20]]//
+
+
+<<run _options.addOption("Numbers are displayed as", "showNumbers")
+.addValueList([["Integers", 2], ["Both", 1], ["Words", 0]])>>
+
+<<if $showNumbers === 1>>
+	<<run _options.addOption("Only numbers up to $showNumbersMax are displayed as words", "showNumbersMax")
+	.addValue("Default (20)", 20).showTextBox()>>
 <</if>>
-</div>
+
+<<print App.UI.DOM.includeDOM(_options.render())>>
diff --git a/src/uncategorized/options.tw b/src/uncategorized/options.tw
index f0d244397a106765780448974386abc8d7c1bd57..68ab3d6269e0fea21e37398462c7de165091b6d8 100644
--- a/src/uncategorized/options.tw
+++ b/src/uncategorized/options.tw
@@ -277,7 +277,7 @@ This save was created using FC version $ver build $releaseID.
 	<div class="content">
 		<h2>Content</h2>
 
-		More granular control of what appears is in [[Description Options]].
+		//More granular control of what appears is in [[Description Options]].//
 
 		<<set _options = new App.UI.OptionsGroup()>>
 
diff --git a/src/uncategorized/summaryOptions.tw b/src/uncategorized/summaryOptions.tw
index c839f964e8536e79801fe1106d8c59dcae6a1875..f913886f8ff630d79360e2f80b8eb287d9fdf433 100644
--- a/src/uncategorized/summaryOptions.tw
+++ b/src/uncategorized/summaryOptions.tw
@@ -11,51 +11,37 @@
 <<set $nextLink = $storedLink>>
 <<set _passageSwitchHandler = App.EventHandlers.optionsChanged>>
 
+<h1>Summary Options</h1>
+
 <p class="scene-intro">
 	These options will affect the short slave summaries that appear on the main menu and the facility management screens.
 </p>
 
-<h3 style="text-align:center">Main menu features</h3>
-<<options $rulesAssistantMain "Summary Options">>
-	Rules Assistant visibility:
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
-
-<<options $abbreviateSidebar "Summary Options">>
-	Facilities in the sidebar are
-	<<option 2 "Summarized">>
-	<<option 1 "Abbreviated">>
-<</options>>
-
-<h3 style="text-align:center">Main Menu slave sorting</h3>
-<<options $sortSlavesMain "Summary Options">>
-	Sorting main menu options are
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
+<h2>Main menu features</h2>
+
+<<set _options = new App.UI.OptionsGroup()>>
+
+<<run _options.addOption("Rules Assistant visibility", "rulesAssistantMain")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Facilities in the sidebar are", "abbreviateSidebar")
+.addValueList([["Summarized", 2], ["Abbreviated", 1]])>>
+
+<<run _options.addOption("Sorting main menu options are", "sortSlavesMain")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
 
 <<if $sortSlavesMain > 0>>
-	<<options $sortSlavesOrder "Summary Options">>
-		in
-		<<option "ascending" "Ascending">>
-		<<option "descending" "Descending">>
-	<</options>>
-
-	<<options $sortSlavesBy "Summary Options">>
-		order and are organized by
-		<<option "devotion" "Devotion">>
-		<<option "name" "Name">>
-		<<option "seniority" "Date purchased">>
-		<<option "actualAge" "Age">>
-		<<option "visualAge" "How old they look">>
-		<<option "physicalAge" "Age of their body">>
-		<<option "assignment" "Assignment">>
-		<<option "weeklyIncome" "Weekly Income">>
-	<</options>>
+	<<run _options.addOption("Sorting direction", "sortSlavesOrder")
+	.addValueList([["Ascending", "ascending"], ["Descending", "descending"]])>>
+
+	<<run _options.addOption("Slaves are sorted by", "sortSlavesBy")
+	.addValueList([["Devotion", "devotion"], ["Name", "name"], ["Date purchased", "seniority"], ["Age", "actualAge"], 
+	["How old they look", "visualAge"], ["Age of their body", "physicalAge"], ["Assignment", "assignment"], ["Weekly Income", "weeklyIncome"]])>>
 <</if>>
 
-<h3 style="text-align:center">Individual panels</h3>
+<<print App.UI.DOM.includeDOM(_options.render())>>
+
+<h2>Individual panels</h2>
 Sample summary:
 <<= App.UI.SlaveList.render.listMarkup(
 	[App.Utils.slaveIndexForId($activeSlave.ID)],
@@ -63,35 +49,26 @@ Sample summary:
 	App.UI.SlaveList.SlaveInteract.stdInteract
 )>>
 
-<<options $slavePanelStyle "Summary Options">>
-	Panel style is
-	<<option 0 "None">>
-	<<option 1 "Line Seperators">>
-	<<option 2 "Card">>
-<</options>>
+<<set _options = new App.UI.OptionsGroup()>>
 
-<<= App.UI.DOM.includeDOM(App.UI.SlaveSummary.displayOptionsFragment(), "dof") >>
+<<run _options.addOption("Panel style is", "slavePanelStyle")
+.addValueList([["None", 0], ["Line Seperator", 1], ["Card", 2]])>>
 
-<<options $summaryStats "Summary Options">>
-	Granular slave stat numbers are
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
+<<run App.UI.SlaveSummary.addOptions(_options)>>
 
-<<options $displayAssignments "Summary Options">>
-Main menu assignment shortcuts are
-	<<option 1 "Shown">>
-	<<option 0 "Hidden">>
-<</options>>
+<<run _options.addOption("Granular slave stat numbers are", "summaryStats")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
+
+<<run _options.addOption("Main menu assignment shortcuts are", "displayAssignments")
+.addValue("Shown", 1).on().addValue("Hidden", 0).off()>>
 
 <<if $showMissingSlaves>>
-	<<options $showMissingSlavesSD "Summary Options">>
-		Missing slave parents are
-		<<option true "Shown">>
-		<<option false "Hidden">>
-	<</options>>
+	<<run _options.addOption("Missing slave parents are", "showMissingSlavesSD")
+	.addValue("Shown", true).on().addValue("Hidden", false).off()>>
 <</if>>
 
+<<print App.UI.DOM.includeDOM(_options.render())>>
+
 <p style="font-style:italic">
 	[[FC Dev's preferred options|Summary Options ][$seeDesk = 0, $seeFCNN = 0, $sortSlavesBy = "devotion",$sortSlavesOrder = "descending",$sortSlavesMain = 0,$rulesAssistantMain = 1, $UI.slaveSummary.abbreviation = {devotion: 1, mental: 1, rules: 1, clothes: 2, health: 1, diet: 1, drugs: 1, hormoneBalance: 1, race: 1, genitalia: 1, physicals: 1, skills: 1, nationality: 1, rulesets: 1, clothes: 0, origins: 0} ,$abbreviateSidebar = 1]]
 </p>