diff --git a/src/main.js b/src/main.js
index ebaf062..6f9f1a6 100644
--- a/src/main.js
+++ b/src/main.js
@@ -39,7 +39,7 @@ refreshFavicon();
const ui = {
app: $('#app'), sidebar: $('#sidebar'), sidebarResizer: $('#sidebar-resizer'), serverAddress: $('#server-address'), port: $('#port'), protocol: $('#protocol'), compression: $('#compression'), downsample: $('#downsample'), connect: $('#connect'),
demo: $('#demo'), status: $('#status'), note: $('#connection-note'), summary: $('#summary'),
- debug: $('#debug-content'), clear: $('#clear'), resetCamera: $('#reset-camera'), scenes: $('#scenes'),
+ debug: $('#debug-content'), clear: $('#clear'), resetCamera: $('#reset-camera'), scenes: $('#scenes'), worldName: $('#world-name'),
sidebarToggle: $('#sidebar-toggle'), viewerTitle: $('.viewer-title'), connectionQrVisibility: $('.connection-qr-visibility'),
connectionSection: $('#connection-section'), connectionAdvanced: $('#connection-advanced'), connectionAdvancedSummary: $('#connection-advanced-summary'),
displaySection: $('#display-section'), displaySectionSummary: $('#display-section-summary'),
@@ -426,6 +426,8 @@ function updateConnectionAdvancedSummary() {
function syncSceneSelector() {
const previous = ui.scenes.value;
+ const world = setupStore.getRoot();
+ ui.worldName.value = world?.isWorld() ? (world.getName() || '—') : '—';
scenes = setupStore.getScenes();
ui.scenes.innerHTML = [
diff --git a/src/styles.css b/src/styles.css
index 7f5a4a0..604c634 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -722,6 +722,7 @@ button.subtle-button.active {
line-height: 1.25;
}
+.display-world,
.display-scenes { margin-bottom: var(--section-space-relaxed); }
.field-heading {
display: flex;
@@ -731,6 +732,7 @@ button.subtle-button.active {
margin-bottom: 6px;
}
.field-heading label { margin: 0; }
+.display-world input,
.display-scenes select { min-height: 34px; }
.toggles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.toggle-column { display: grid; align-content: start; gap: var(--section-space); }
diff --git a/tests/ui-contract.test.mjs b/tests/ui-contract.test.mjs
index 7433509..4614da7 100644
--- a/tests/ui-contract.test.mjs
+++ b/tests/ui-contract.test.mjs
@@ -32,3 +32,20 @@ test('every hard-coded #id selector in the main UI map exists in index.html', ()
assert.deepEqual(missing, []);
});
+
+
+test('Display shows the current World as a read-only field above Scenes', () => {
+ const display = indexSource.match(//)?.[0];
+ assert.ok(display, 'Display panel must exist');
+
+ const field = display.match(/]*id="world-name"[^>]*>/)?.[0];
+ assert.ok(field, 'World field must exist');
+ assert.match(field, /\breadonly\b/);
+ assert.ok(display.indexOf('id="world-name"') < display.indexOf('id="scenes"'));
+
+ const sync = mainSource.match(/function syncSceneSelector\(\) \{([\s\S]*?)\n\}/)?.[1];
+ assert.ok(sync, 'scene selector synchronization must exist');
+ assert.match(sync, /setupStore\.getRoot\(\)/);
+ assert.match(sync, /ui\.worldName\.value\s*=/);
+ assert.match(sync, /world\.getName\(\)/);
+});