diff --git a/web/index.html b/web/index.html
index 737a4d9..6946c33 100644
--- a/web/index.html
+++ b/web/index.html
@@ -138,7 +138,10 @@ try {
// Adaptive to plan density: a large generated city (Lane A) has content in nearly every chunk, so
// a smaller radius + no sun-shadow pass keeps draw calls near the ≤300 gate. The sparse fixture
// gets the fuller radius 3 + shadows (measured ~140 draws). Override via ?r= / ?shadows=0|1.
-const BIG_CITY = (plan.shops?.length || 0) > 120;
+// [Lane F R19 — B's proven one-liner] a real town can have FEW shops but a HUGE road graph (real Katoomba:
+// 20 shops / 799 edges / 5 km) — the shop-count heuristic alone left it on small-town streaming and blew the
+// tri budget (280k > 200k). Extend the trigger to the graph size so big-graph towns stream like big cities.
+const BIG_CITY = (plan.shops?.length || 0) > 120 || (plan.streets?.edges?.length || 0) > 200;
const RADIUS = parseInt(params.get('r'), 10) || (BIG_CITY ? 2 : 3);
const SHADOWS = params.has('shadows') ? params.get('shadows') !== '0' : !BIG_CITY;
const canvas = document.getElementById('c');