diff --git a/README.md b/README.md index e3833a654..1b1fc46a0 100644 --- a/README.md +++ b/README.md @@ -488,7 +488,7 @@ How the globe handles live data: ``` src/ ├── main.js # Bootstrap: Google 3D tiles, layer registration -├── ui.js # Runtime UI — panels, HUD, styles, control facade +├── ui/ # Runtime UI — panels, HUD, styles, controls ├── hud.js # Intelligence HUD + AI scene summary ├── keySetup.js # POWER UP panel — in-app provider keys (dev server only) ├── mapStackController.js # Basemap switching — Google 3D / Esri / OSM / ion stacks diff --git a/docs/CODE-BOUNDARIES.md b/docs/CODE-BOUNDARIES.md index 3362b98f0..9085a7b72 100644 --- a/docs/CODE-BOUNDARIES.md +++ b/docs/CODE-BOUNDARIES.md @@ -235,7 +235,7 @@ DOM elements and callbacks; importing it creates no browser state. `destroy()` removes owned listeners and cancels pending work without changing saved state or moving focus. Call it before removing or replacing the controls. -`src/ui/composition.js` retains panel layout, persistence, share restoration and application +`src/ui/applicationShell.js` retains panel layout, persistence, share restoration and application reactions to state changes. Map Source selection and Location draft cleanup are provided through callbacks. The component imports no globe, data, application or server modules. Package checks and scoped formatting cover this entry. diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 7184c5d96..714cb30f1 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -5373,7 +5373,7 @@ demand with square-root demand scaling and semantic layer weights (`labelArbiter.js:181`). First-run default: ELASTIC. **A default has THREE surfaces, and a PARSE fallback that is not one of them.** -The value literals (engine constant, markup value, markup readout, `ui.js` +The value literals (engine constant, markup value, markup readout, `src/ui/visualPresets.js` `GLOBAL_POST_DEFAULTS`, the share generator's starting state) must all move together, because a fresh boot runs no restore and those literals ARE the startup state. The `scf` / `ko` PARSE fallbacks deliberately do NOT move: they answer @@ -5421,7 +5421,7 @@ easier to meet (detection is now on more often), but does not create it. - **Detection OUTSIDE opacity: `1%`** (moved `5% → 3% → 1%` on 2026-08-24). `KEYHOLE_OUTSIDE_OPACITY_DEFAULT` in `src/celestialRing.js`, mirrored by `#detection-opacity-slider`'s markup value AND readout, - `GLOBAL_POST_DEFAULTS.detectionOutsideOpacityPct` in `ui.js`, and + `GLOBAL_POST_DEFAULTS.detectionOutsideOpacityPct` in `src/ui/visualPresets.js`, and `_detectionOutsideOpacityPct` in `sharelink.js`. The slider's `step` is now `1`, so 1–4 % are reachable at all (at the previous step of 5 the entire sub-default range was one stop wide). `AIRCRAFT_BRACKET_FLOOR_ANCHOR` in diff --git a/scripts/qa-cockpit-plates.mjs b/scripts/qa-cockpit-plates.mjs index 4e725fd8f..3d3aece03 100644 --- a/scripts/qa-cockpit-plates.mjs +++ b/scripts/qa-cockpit-plates.mjs @@ -12,7 +12,7 @@ * passed with the painter stubbed out — the number was right and nothing was * drawn. Every assertion here now comes from the RENDERED path instead: * - * ids/counts — `styleManager.getDetectionDiagnostics()` (src/ui.js), the + * ids/counts — `styleManager.getDetectionDiagnostics()` (src/ui/shellFacade.js), the * overlay's own published `visibleCount` / `labeledKeys`, so a contact only * counts once the sweep, the arbiter and the placement solve have all run. * plate scale — tapped off `CanvasRenderingContext2D` while the frame paints. diff --git a/scripts/qa-l9-matrix.mjs b/scripts/qa-l9-matrix.mjs index fdac4fd40..8709366de 100644 --- a/scripts/qa-l9-matrix.mjs +++ b/scripts/qa-l9-matrix.mjs @@ -1884,7 +1884,7 @@ async function runBrowserGroup(record) { await step('C15', async () => { // CRT/NVG/FLIR are DISPLAY LABELS; the real style ids are retro / - // surveillance / thermal (src/ui.js STYLE_STATUS_LABELS). Passing the + // surveillance / thermal (src/ui/visualPresets.js STYLE_STATUS_LABELS). Passing the // labels made every call a silent no-op that still "passed" — so assert // the returned visual state actually changed to the requested style. const wanted = [['retro', 'CRT'], ['surveillance', 'NVG'], ['thermal', 'FLIR'], ['normal', 'Normal']]; diff --git a/src/contactsDetectionPolicy.test.mjs b/src/contactsDetectionPolicy.test.mjs index 862d055ce..8fe78e1de 100644 --- a/src/contactsDetectionPolicy.test.mjs +++ b/src/contactsDetectionPolicy.test.mjs @@ -281,7 +281,7 @@ test('detection is wired to the Contacts transaction, and cockpit no longer touc uiSource.indexOf('_syncContactsDetection() {'), uiSource.indexOf('/** Apply a temporary cockpit-only'), ); - assert.ok(helper.length > 0, 'the Contacts detection helper is present in ui.js'); + assert.ok(helper.length > 0, 'the Contacts detection helper is present in the UI shell source'); assert.match(helper, /if \(this\._contextModeChanging\) return;/, 'fires at settle, not at click'); assert.match(helper, /active: this\._contextMode === 'flights'/); assert.match(helper, /styleOwnsDetection:\s*!this\._detectionUserOverridden/); @@ -302,7 +302,7 @@ test('detection is wired to the Contacts transaction, and cockpit no longer touc uiSource.indexOf('_setCockpitVision(mode, active, { revealParameters = false } = {}) {'), uiSource.indexOf('_syncIrBoost() {'), ); - assert.ok(visionHook.length > 0, 'the cockpit vision hook is present in ui.js'); + assert.ok(visionHook.length > 0, 'the cockpit vision hook is present in the UI shell source'); assert.doesNotMatch(visionHook, /etection/, 'cockpit transitions must not touch detection'); }); diff --git a/src/loadingFeedback.test.mjs b/src/loadingFeedback.test.mjs index 19c660702..b9903f97e 100644 --- a/src/loadingFeedback.test.mjs +++ b/src/loadingFeedback.test.mjs @@ -628,7 +628,7 @@ test('the loading ticker never runs hidden and stops after loading and notices s // safety-net poll, so its `if (document.hidden) return;` is correct there // and must not be confused with this self-stopping ticker's leak. const armBody = ui.slice(ui.indexOf('_armLoadingFeedbackTicker() {')); - assert.ok(armBody.startsWith('_armLoadingFeedbackTicker() {'), 'ticker function not found in ui.js'); + assert.ok(armBody.startsWith('_armLoadingFeedbackTicker() {'), 'ticker function not found in the UI shell source'); const arm = armBody.slice(0, armBody.indexOf('\n }\n') + 5); // 1. The ARM guard itself refuses while hidden. Previously the only hidden diff --git a/src/scenes/director.test.mjs b/src/scenes/director.test.mjs index 59f3a3a0e..1077b0658 100644 --- a/src/scenes/director.test.mjs +++ b/src/scenes/director.test.mjs @@ -1264,7 +1264,7 @@ test('applyVisualState gates the map-stack switch on both sides of its await', ( // switch would otherwise stand on the globe. const source = readShellSource(); const method = source.match(/\n {2}async applyVisualState\([\s\S]*?\n {2}\}\n/); - assert.ok(method, 'applyVisualState is missing from ui.js'); + assert.ok(method, 'applyVisualState is missing from the UI shell source'); assert.match(method[0], /async applyVisualState\(state = \{\}, \{ isCurrent = null \} = \{\}\)/); const mapStackBlock = method[0].match(/if \(state\.mapStack\) \{[\s\S]*?\n {4}\}/);