diff --git a/game/03-JavaScript/base.js b/game/03-JavaScript/base.js
index bb7c30f639556d3b925bc26e3f3254abb3e7b2c4..2b8b7754753248f71cfe2a9350f192068be131a1 100644
--- a/game/03-JavaScript/base.js
+++ b/game/03-JavaScript/base.js
@@ -166,7 +166,7 @@ window.wetnessKeyword = wetnessKeyword;
 
 /**
  * Returns an optional wetness prefix for the article of clothing.
- 
+
  * @param {string} slot clothing article slot used
  * @returns {string} printable integrity prefix
  */
@@ -746,3 +746,46 @@ Macro.add("carriedClear", {
 		carriedClear(this.args[0]);
 	},
 });
+
+// create text map link
+Macro.add("tml", {
+	handler() {
+		// name of the linked location
+		const target = this.args[0];
+
+		const link = document.createElement("a");
+		link.classList.add("no-numberify");
+		link.title = target;
+		// shorten street names to the first two letters
+		link.text = target.includes("Street") ? ` ${target.slice(0, 2)} ` : "─┼─";
+
+		let type = "locked";
+		if (target === V.passage) type = "current";
+		else if (V.possessed && target === V.nextPassageCheck) type = "possessed next";
+		else if (V.map.available[V.passage].includes(target) || V.debug) type = V.possessed ? "possessed" : "normal";
+		switch (type) {
+			case "current":
+				link.id = "currentLoc";
+				link.title += " (you are here)";
+				break;
+			case "possessed next":
+				link.classList.add("nextLink");
+				link.title += " (0:05)";
+				link.onclick = () => Engine.play(V.nextPassage);
+				break;
+			case "possessed":
+				link.title += " (0:05)";
+				link.onclick = () => Engine.play(V.nextPassage);
+				break;
+			case "normal":
+				link.title += " (0:05)";
+				link.onclick = () => mapMove(target);
+				break;
+			case "locked":
+				link.classList.add("lockedLoc");
+				break;
+		}
+
+		this.output.append(link);
+	},
+});
diff --git a/game/base-system/overlays/options.twee b/game/base-system/overlays/options.twee
index 7f7370146622a77ba414230b45bcfddd0ac3e2af..515ece8b8466aef1e07c61251d3130ddd9de1148 100644
--- a/game/base-system/overlays/options.twee
+++ b/game/base-system/overlays/options.twee
@@ -177,7 +177,7 @@ IMPORTANT:
 		<div class="settingsGrid">
 			<div class="settingsHeader options">Map</div>
 			<div class="settingsToggleItem">
-				<label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.mapMovement" false true autocheck>> Enable map movement by clicking/touching the map icons</label>
+				<label data-target="images"><<checkbox "$options.mapMovement" false true autocheck>> Enable map movement by clicking/touching the map icons</label>
 			</div>
 			<div class="settingsToggleItem">
 				<label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.mapLegacy" false true autocheck>> Disable SVG map. Enable if town map is not visible.</label>
@@ -186,7 +186,7 @@ IMPORTANT:
 				<label data-target="['images', 'maplegacy]" data-disabledif="V.options.images===0||V.options.mapLegacy"><<checkbox "$options.mapMarkers" false true autocheck>> Show clickable area on map</label>
 			</div>
 			<div class="settingsToggleItem">
-				<label data-target="images" data-disabledif="V.options.images===0"><<checkbox "$options.mapTop" false true autocheck>> Move the map above the map links</label>
+				<label data-target="images"><<checkbox "$options.mapTop" false true autocheck>> Move the map above the map links</label>
 			</div>
 		</div>
 	<</if>>
diff --git a/game/base-system/widgets.twee b/game/base-system/widgets.twee
index 7f29e69919f045e9bc81fa08dd7b995cb78197de..3bf0914cd4c28b9009705b3d4283351ffa62a7a0 100644
--- a/game/base-system/widgets.twee
+++ b/game/base-system/widgets.twee
@@ -2878,49 +2878,18 @@
 <</widget>>
 
 <<widget "textmap">>
-	<<if $options.mapMovement is true and !$possessed>>
-		__Map__<br>
-		<pre>
-  <a class="no-numberify mapmove" onclick="mapMove('Barb Street')" title="Barb Street">Ba</a>
-—
-<a class="no-numberify mapmove" onclick="mapMove('Cliff Street')" title="Cliff Street">Cl</a>
-—
-<a class="no-numberify mapmove" onclick="mapMove('Starfish Street')" title="Starfish Street">St</a>
-—
-<a class="no-numberify mapmove" onclick="mapMove('Mer Street')" title="Mer Street">Me</a>
-<br>
- /  \ /  \ /  \ /  \
-<br>
-<a class="no-numberify mapmove" onclick="mapMove('Domus Street')" title="Domus Street">Do</a>
-<a class="no-numberify mapmove" onclick="mapMove('Residential alleyways')" title="ResidentialAlley">—</a>
-<a class="no-numberify mapmove" onclick="mapMove('Connudatus Street')" title="Connudatus Street">Co</a>
-<a class="no-numberify mapmove" onclick="mapMove('Commercial alleyways')" title="CommercialAlley">—</a>
-<a class="no-numberify mapmove" onclick="mapMove('High Street')" title="High Street">Hi</a>
-<a class="no-numberify mapmove" onclick="mapMove('Park')" title="Park">—</a>
-<a class="no-numberify mapmove" onclick="mapMove('Oxford Street')" title="Oxford Street">Ox</a>
-<a class="no-numberify mapmove" onclick="mapMove('Industrial alleyways')" title="IndustrialAlley">—</a>
-<a class="no-numberify mapmove" onclick="mapMove('Harvest Street')" title="Harvest Street">Ha</a>
-<br>
- \  / \  / \  / \  /
-<br>
-  <a class="no-numberify mapmove" onclick="mapMove('Danube Street')" title="Danube Street">Da</a>
-—
-<a class="no-numberify mapmove" onclick="mapMove('Wolf Street')" title="Wolf Street">Wo</a>
-—
-<a class="no-numberify mapmove" onclick="mapMove('Nightingale Street')" title="Nightingale Street">Ni</a>
-—
-<a class="no-numberify mapmove" onclick="mapMove('Elk Street')" title="Elk Street">El</a>
-<br>
-		</pre>
+	<<if V.options.mapMovement>>
+		<div id="textmap">
+			╔═<<tml "Barb Street">>═╦═<<tml "Cliff Street">>═╦═<<tml "Starfish Street">>═╦═<<tml "Mer Street">>═╗<br>
+			<<tml "Domus Street">><<tml "Residential alleyways">><<tml "Connudatus Street">><<tml"Commercial alleyways">><<tml "High Street">><<tml "Park">><<tml "Oxford Street">><<tml "Industrial alleyways">><<tml "Harvest Street">><br>
+			╚═<<tml "Danube Street">>═╩═<<tml "Wolf Street">>═╩═<<tml "Nightingale Street">>═╩═<<tml "Elk Street">>═╝<br>
+		</div>
 	<<else>>
-		__Map__<br>
-		<pre>
-  Ba — Cl — St — Me<br>
- /  \ /  \ /  \ /  \<br>
-Do — Co — Hi — Ox — Ha<br>
- \  / \  / \  / \  /<br>
-  Da — Wo — Ni — El<br>
-		</pre>
+		<div id="textmap">
+			╔═ Ba ═╦═ Cl ═╦═ St ═╦═ Me ═╗<br>
+			Do ─┼─ Co ─┼─ Hi ─┼─ Ox ─┼─ Ha<br>
+			╚═ Da ═╩═ Wo ═╩═ Ni ═╩═ El ═╝<br>
+		</div>
 	<</if>>
 	<br>
 <</widget>>
diff --git a/modules/css/base.css b/modules/css/base.css
index 2dc33f82020619173a76831e26917f0a967f68f0..ffef7b57c46b80719932a40d4a96276d2940402a 100644
--- a/modules/css/base.css
+++ b/modules/css/base.css
@@ -35,6 +35,20 @@ a:hover {
 	color: var(--link-hover);
 }
 
+#textmap {
+	font-family: monospace;
+	line-height: 200%;
+}
+#textmap a {
+	padding: 0;
+}
+#textmap>#currentLoc, #textmap>#currentLoc:hover {
+	color: var(--gold);
+}
+#textmap>.lockedLoc a {
+	color: var(--000);
+}
+
 img,
 canvas {
 	image-rendering: pixelated;
@@ -2983,7 +2997,7 @@ a[target="_blank"]::after {
 	color: transparent;
 }
 
-.nextLink a {
+.nextLink {
 	background: var(--link);
 	text-shadow: 0 0 7px var(--150), 0 0 22px var(--purple), 0 0 32px var(--purple);
 	background-clip: text;