diff --git a/src/005-passages/endWeekPassages.js b/src/005-passages/endWeekPassages.js
index e42545598c14c10cf5f15bf42aeb578aa3bc6208..33e93c72fd560dbca0439cc4605bb0ba91690c5c 100644
--- a/src/005-passages/endWeekPassages.js
+++ b/src/005-passages/endWeekPassages.js
@@ -28,3 +28,12 @@ new App.DomPassage("Next Week",
 		return document.createDocumentFragment();
 	}
 );
+
+new App.DomPassage("Economics",
+	() => {
+		V.nextButton = "Continue";
+		V.nextLink = "Scheduled Event";
+
+		return App.EndWeek.economics();
+	}
+);
diff --git a/src/Mods/SecExp/js/authorityReport.js b/src/Mods/SecExp/js/authorityReport.js
index d21ba717cbabf41ca0a1840f0e888ce5e31e10b6..cf89347fb30b09449712ce35001d987926ffd076 100644
--- a/src/Mods/SecExp/js/authorityReport.js
+++ b/src/Mods/SecExp/js/authorityReport.js
@@ -451,5 +451,5 @@ App.SecExp.authorityReport = function() {
 
 		App.SecExp.generator.rebellion(); // rolls for rebellions
 	}
-	return r.join(" ");
+	return App.Events.makeNode(r);
 };
diff --git a/src/Mods/SecExp/js/securityReport.js b/src/Mods/SecExp/js/securityReport.js
index 732116d1b0fa17e0822cfba74e1fb2fb79329f7d..62b25f5b6a03f5890895b4d97a3c0c129ce62069 100644
--- a/src/Mods/SecExp/js/securityReport.js
+++ b/src/Mods/SecExp/js/securityReport.js
@@ -1,3 +1,4 @@
+/** @returns {DocumentFragment} */
 App.SecExp.securityReport = function() {
 	let immigration = 0, emigration = 0, secGrowth = 0, crimeGrowth = 0;
 	if (V.ACitizens > V.oldACitizens) {
diff --git a/src/uncategorized/economics.js b/src/uncategorized/economics.js
new file mode 100644
index 0000000000000000000000000000000000000000..d8940eb809caaee38e5fbfc9c68eb53a2e2e66d0
--- /dev/null
+++ b/src/uncategorized/economics.js
@@ -0,0 +1,88 @@
+App.EndWeek.economics = function() {
+	const node = new DocumentFragment();
+	App.UI.DOM.appendNewElement("h1", node, `${V.arcologies[0].name} Weekly Financial Report — Week ${V.week}`);
+
+	if (V.cash > -10000) {
+		V.debtWarned = 0;
+	}
+
+	SectorCounts();
+	App.Arcology.updateOwnership();
+
+	node.append(App.EndWeek.marketsReport());
+
+	/**
+	 * @typedef {Object} economicsReport
+	 * @property {string} name
+	 * @property {boolean} requirements
+	 * @property {DocumentFragment|HTMLElement} report
+	 */
+
+	/** @type {Map<string, economicsReport>} */
+	const reportsMap = new Map([
+		["arcologies", {
+			name: "Arcologies",
+			requirements: true,
+			get report() { return App.EndWeek.neighborsDevelopment(); }
+		}],
+		["management", {
+			name: "Arcology Management",
+			requirements: true,
+			get report() { return App.EndWeek.arcManagement(); }
+		}],
+		["societies", {
+			name: "Society Development",
+			get requirements() { return V.FSAnnounced > 0; },
+			get report() { return App.EndWeek.FSDevelopments(); }
+		}],
+		["corporation", {
+			name: "Corporation Developments",
+			get requirements() { return V.corp.Incorporated === 1; },
+			get report() { return App.EndWeek.corporationDevelopments(); }
+		}],
+		["authority", {
+			name: "Authority",
+			get requirements() { return V.secExpEnabled > 0; },
+			get report() { return App.SecExp.authorityReport(); }
+		}],
+		["securityReport", {
+			name: "Security",
+			get requirements() { return V.secExpEnabled > 0; },
+			get report() { return App.SecExp.securityReport(); }
+		}],
+		["reputation", {
+			name: "Reputation",
+			requirements: true,
+			get report() { return App.EndWeek.reputation(); }
+		}],
+		["business", {
+			name: "Personal Business",
+			requirements: true,
+			get report() { return App.EndWeek.personalBusiness(); }
+		}],
+		["personal", {
+			name: "Personal Notes",
+			get requirements() { return (V.PC.boobs >= 1000 || V.PC.pregKnown === 1 || V.playerAging !== 0); },
+			get report() { return App.EndWeek.personalNotes(); }
+		}],
+
+	]);
+
+	if (V.useTabs === 0) {
+		for (const report of reportsMap.values()) {
+			if (report.requirements) {
+				node.append(report.report);
+			}
+		}
+	} else {
+		const tabBar = new App.UI.Tabs.TabBar("Economics");
+		for (const [title, report] of reportsMap) {
+			if (report.requirements) {
+				tabBar.addTab(report.name, title, report.report);
+			}
+		}
+		node.append(tabBar.render());
+	}
+
+	return node;
+};
diff --git a/src/uncategorized/economics.tw b/src/uncategorized/economics.tw
deleted file mode 100644
index e4eccc61eddf2f5f1b5bbe79ea3220e7caaa4a4b..0000000000000000000000000000000000000000
--- a/src/uncategorized/economics.tw
+++ /dev/null
@@ -1,133 +0,0 @@
-:: Economics [nobr]
-
-<h1>
-	<<print $arcologies[0].name + " Weekly Financial Report — Week " + $week>>
-</h1>
-
-<<set $nextButton = "Continue", $nextLink = "Scheduled Event">>
-
-<<if $cash > -10000>>
-	<<set $debtWarned = 0>>
-<</if>>
-
-<<run SectorCounts()>>
-<<run App.Arcology.updateOwnership()>>
-
-<<includeDOM App.EndWeek.marketsReport()>>
-
-<<if $useTabs == 0>>
-	<<includeDOM App.EndWeek.neighborsDevelopment()>>
-	<<includeDOM App.EndWeek.arcManagement()>>
-
-	<<if $FSAnnounced > 0>>
-		<p>
-			<<includeDOM App.EndWeek.FSDevelopments();>>
-		</p>
-	<</if>>
-
-	<<if $corp.Incorporated == 1>>
-		<<includeDOM App.EndWeek.corporationDevelopments()>>
-	<</if>>
-
-	<<if $secExpEnabled > 0>>
-		<br>
-		<<= App.SecExp.authorityReport()>>
-		<<includeDOM App.SecExp.securityReport()>>
-	<</if>>
-
-	<<includeDOM App.EndWeek.reputation()>>
-	<<includeDOM App.EndWeek.personalBusiness()>>
-
-	<<if $PC.boobs >= 1000 || $PC.pregKnown == 1 || $playerAging != 0>>
-		<<includeDOM App.EndWeek.personalNotes()>>
-	<</if>>
-
-<<else>>
-	<body>
-		<div class="tab-bar">
-			<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Arcologies')" id="defaultOpen">Arcologies</button>
-			<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Management')">Arcology Management</button>
-			<<if $FSAnnounced > 0>>
-				<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Societies')">Society Development</button>
-			<</if>>
-			<<if $corp.Incorporated == 1>>
-				<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Corporation')">Corporation Developments</button>
-			<</if>>
-			<<if $secExpEnabled > 0>>
-				<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Authority')">Authority</button>
-				<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'securityReport')">Security</button>
-			<</if>>
-			<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Reputation')">Reputation</button>
-			<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Business')">Personal Business</button>
-			<<if $PC.boobs >= 1000 || $PC.pregKnown == 1 || $playerAging != 0>>
-				<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Personal')">Personal Notes</button>
-			<</if>>
-		</div>
-
-		<div id="Arcologies" class="tab-content">
-			<div class="content">
-				<<includeDOM App.EndWeek.neighborsDevelopment()>>
-			</div>
-		</div>
-
-		<div id="Management" class="tab-content">
-			<div class="content">
-				<<includeDOM App.EndWeek.arcManagement()>>
-			</div>
-		</div>
-
-		<<if $FSAnnounced > 0>>
-			<div id="Societies" class="tab-content">
-				<div class="content">
-					<<includeDOM App.EndWeek.FSDevelopments()>>
-				</div>
-			</div>
-		<</if>>
-
-		<<if $corp.Incorporated == 1>>
-			<div id="Corporation" class="tab-content">
-				<div class="content">
-					<<includeDOM App.EndWeek.corporationDevelopments()>>
-				</div>
-			</div>
-		<</if>>
-
-		<<if $secExpEnabled > 0>>
-			<div id="Authority" class="tab-content">
-				<div class="content">
-					<<= App.SecExp.authorityReport()>>
-				</div>
-			</div>
-
-			<div id="securityReport" class="tab-content">
-				<div class="content">
-					<<includeDOM App.SecExp.securityReport()>>
-				</div>
-			</div>
-		<</if>>
-
-		<div id="Reputation" class="tab-content">
-			<div class="content">
-				<<includeDOM App.EndWeek.reputation()>>
-			</div>
-		</div>
-
-		<div id="Business" class="tab-content">
-			<div class="content">
-				<<includeDOM App.EndWeek.personalBusiness()>>
-			</div>
-		</div>
-
-		<<if $PC.boobs >= 1000 || $PC.pregKnown == 1 || $playerAging != 0>>
-			<div id="Personal" class="tab-content">
-				<div class="content">
-					<<includeDOM App.EndWeek.personalNotes()>>
-				</div>
-			</div>
-		<</if>>
-
-		<script>
-			document.getElementById("defaultOpen").click();
-		</script>
-	</body>
-<</if>>