diff --git a/public/app.js b/public/app.js
index 01d989d4..efc1a482 100644
--- a/public/app.js
+++ b/public/app.js
@@ -42,6 +42,18 @@ function transportBadge(rt, scopeName) {
return ' ' + escapeHtml(label) + '';
}
+/**
+ * Dedicated Scope column cell (as opposed to transportBadge's inline pill
+ * on the Type column) — same three-state semantics: non-transport routes
+ * show a dash, transport routes with no resolved region show a muted
+ * "unknown", and a resolved match shows the region name.
+ */
+function scopeCellHtml(rt, scopeName) {
+ if (!isTransportRoute(rt)) return '—';
+ if (scopeName) return '' + escapeHtml(scopeName) + '';
+ return 'unknown';
+}
+
/**
* Compute breakdown byte ranges from raw_hex on the client.
* Mirrors cmd/server/decoder.go BuildBreakdown(). Used so per-observation raw_hex
diff --git a/public/packets.js b/public/packets.js
index ed585cee..e056ef92 100644
--- a/public/packets.js
+++ b/public/packets.js
@@ -1626,7 +1626,7 @@
Region
Time
Hash
Size
HB
-
Type
Observer
Path
Rpt
Details
+
Type
Scope
Observer
Path
Rpt
Details
@@ -2010,6 +2010,7 @@
{ key: 'hash', label: 'Hash' },
{ key: 'size', label: 'Size' },
{ key: 'type', label: 'Type' },
+ { key: 'scope', label: 'Scope' },
{ key: 'observer', label: 'Observer' },
{ key: 'path', label: 'Path' },
{ key: 'rpt', label: 'Rpt' },
@@ -2019,7 +2020,7 @@
// #1249: observer column must stay visible at narrow widths so the IATA
// badge (#1188) renders on mobile. Without observer in scope the user
// can't see who heard the packet at all.
- const defaultHidden = isNarrow ? ['region', 'hash', 'path', 'rpt', 'size'] : ['region'];
+ const defaultHidden = isNarrow ? ['region', 'hash', 'path', 'rpt', 'size', 'scope'] : ['region'];
let visibleCols;
try {
visibleCols = JSON.parse(localStorage.getItem('packets-visible-cols'));
@@ -2264,6 +2265,7 @@