diff --git a/CHANGELOG.md b/CHANGELOG.md index 19dfc8b3..81c91a45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ # Changelog +## Sprint 161 Widescreen workbench support (2026-07-10) + +- Added dedicated `1800px` and `2200px` frontend layout breakpoints for wide and ultrawide monitors. +- Expanded the workbench shell, inspector and MapLibre review frame while preserving the existing Map/Data/QA/AI/Export workflows and API contracts. +- Added regression tests for widescreen grid, map-height and ultrawide layout contracts. +- No backend API, database migration, model default, provider fetching, fake detection output or model download behavior changed. + ## Sprint 160 Split-background promotion preflight (2026-07-10) - Added `--preflight-only` to `scripts/run_split_background_promotion_workflow.sh`. diff --git a/backend/tests/test_sprint161_widescreen_workbench.py b/backend/tests/test_sprint161_widescreen_workbench.py new file mode 100644 index 00000000..620751fa --- /dev/null +++ b/backend/tests/test_sprint161_widescreen_workbench.py @@ -0,0 +1,29 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[2] + + +def test_workbench_adds_widescreen_layout_contracts() -> None: + css = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8") + + assert "Sprint 161 widescreen workbench support" in css + assert "@media (min-width: 1800px)" in css + assert "grid-template-columns: 14rem minmax(0, 1fr) 24rem;" in css + assert ".workbench-main {\n padding: 1.1rem 1.35rem 1.35rem;" in css + assert ".workspace-grid-data {\n grid-template-columns: repeat(3, minmax(0, 1fr));" in css + assert ".workspace-grid-data > section:nth-child(3) {\n grid-column: auto;" in css + assert ".workbench-main .map-container,\n .map-frame-surface .map-container" in css + assert "height: calc(100vh - 18rem);" in css + assert "min-height: 36rem;" in css + + +def test_workbench_adds_ultrawide_map_priority_contracts() -> None: + css = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8") + + assert "@media (min-width: 2200px)" in css + assert "grid-template-columns: 15rem minmax(0, 1fr) 26rem;" in css + assert ".workspace-grid-data,\n .workspace-grid-analysis,\n .workspace-grid-ai,\n .workspace-grid-exports" in css + assert "grid-template-columns: repeat(4, minmax(0, 1fr));" in css + assert "height: calc(100vh - 15.5rem);" in css + assert "min-height: 42rem;" in css diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index ff110b1b..6957c18a 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -6390,3 +6390,38 @@ Open: - Redeploy/pull on Tower, then run: - `PROMOTION_POSITIVE_PORTFOLIO_PATH=... OPERATOR_SAMPLE_MANIFEST_PATH=... bash scripts/run_split_background_promotion_workflow.sh --preflight-only http://192.168.10.150:1202` - If preflight passes, rerun without `--preflight-only` to generate the split summary and split-aware promotion report. + +# Sprint 161 - Widescreen workbench support + +## What changed + +- Added dedicated frontend CSS breakpoints for `1800px` and `2200px` workbench widths. +- Wide screens now expand the workbench shell columns, inspector padding, Data/Analysis/AI/Export grids and Map workspace controls without changing workflows. +- Ultrawide screens prioritize the MapLibre review frame with a taller map and wider toolbar/inspection layout. +- Added static regression coverage for widescreen/ultrawide layout contracts. +- Updated frontend README, TODO and changelog. + +## What was tested + +- Red step: `python -m pytest tests/test_sprint161_widescreen_workbench.py -q` failed before the widescreen CSS contracts existed. +- Ran `python -m pytest tests/test_sprint161_widescreen_workbench.py tests/test_sprint53_selection_ergonomics.py tests/test_sprint85_map_workspace_density.py tests/test_sprint113_calm_workbench_layout.py -q`: 13 passed. +- Ran `python -m compileall backend/app`. +- Ran `python -m pytest` in `backend`: 449 passed, 17 existing Pydantic protected-namespace warnings. +- Ran `npm run typecheck` in `frontend`. +- Ran `npm run build` in `frontend`. +- Ran `python -m alembic heads` in `backend`: `202606120900 (head)`. +- Ran `python -m alembic upgrade head --sql` in `backend`. +- Ran `bash -n scripts/live_migration_smoke.sh`. +- Ran `bash scripts/run_readiness_check.sh`: passed. +- Ran a local Vite preview visual/layout check at `2560x1080` through the in-app browser. The workbench measured no horizontal overflow, shell columns `240px 1889px 416px`, and the Map workspace rendered an `832px` high MapLibre frame with the road basemap visible. + +## Known limitations + +- Local `docker compose config` could not be run on this Windows workstation because the Docker CLI is not installed or not on `PATH`. +- The live Tower/Unraid runtime at `http://192.168.10.150:1202` will show the widescreen changes only after redeploying this commit. +- The local preview showed an expected API error because it served the built frontend without the Docker backend proxy; the layout and MapLibre basemap rendered correctly. + +## Next recommended pass + +- Redeploy/pull this commit on Tower/Unraid and visually recheck `http://192.168.10.150:1202` on the actual widescreen monitor. +- Continue with the split-background promotion preflight/matrix flow once the runtime has been rebuilt. diff --git a/docs/TODO.md b/docs/TODO.md index a5ef0cbd..dad6234c 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -91,6 +91,7 @@ This file now starts with the current implementation status. Older preparation/b - [x] Add QA/QC and Exports usability layout pass with calmer evidence review and handoff artifact scanning. - [x] Add AI Labs Detection/Segmentation hierarchy and result density polish. - [x] Add Export/System handoff hierarchy and provider registry density polish. +- [x] Add widescreen and ultrawide workbench breakpoints for the map-first GIS workflow. - [x] Add operator-provided real raster/reference detection + QA workflow smoke. - [x] Validate the configured building model on a real georeferenced Kempen orthophoto/GeoTIFF with persisted reference vectors and QA/QC metrics. - [x] Fix configured-YOLO mixed-case class labels so `Building` model output matches `building` domain filters. diff --git a/frontend/README.md b/frontend/README.md index 604dab64..6317b631 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -8,6 +8,8 @@ The shell has a calmer V1 workbench density pass: the duplicated workspace comma Data and Map have an additional usability layout pass for the core daily workflow. The Data workspace uses compact catalog cards, shorter action buttons and tighter role summaries. The Map workspace prioritizes the MapLibre frame before dense controls, gives the map more height on desktop and compresses context/provenance/bbox extraction surfaces while preserving the existing selection, export and QA actions. +Wide and ultrawide screens now get dedicated workbench breakpoints at `1800px` and `2200px`. These keep the sidebar and inspector readable, expand the MapLibre review frame and use extra horizontal space for Data, Analysis, AI and Export grids without changing API calls or workflows. + The Map workspace defaults to an OpenStreetMap road basemap with visible attribution so uploaded vectors, AOIs and QA overlays appear on a real street context. Set `VITE_MAP_STYLE_URL` to a managed MapLibre style URL to override this for production or high-volume deployments. When the public OpenStreetMap fallback is active, the Map workspace shows a basemap usage notice. This keeps the local/demo default honest and reminds operators to configure a managed style URL before production or heavier tile traffic. diff --git a/frontend/src/styles/app.css b/frontend/src/styles/app.css index 60f7b118..c3a597cf 100644 --- a/frontend/src/styles/app.css +++ b/frontend/src/styles/app.css @@ -5193,6 +5193,89 @@ section { font-size: 0.82rem; } +/* Sprint 161 widescreen workbench support: use extra horizontal space without changing workflows. */ +@media (min-width: 1800px) { + .workbench-topbar { + grid-template-columns: minmax(14rem, 20rem) minmax(0, 1fr); + padding-inline: 1.35rem; + } + + .context-bar > div { + max-width: 16rem; + } + + .workbench-layout { + grid-template-columns: 14rem minmax(0, 1fr) 24rem; + } + + .workbench-main { + padding: 1.1rem 1.35rem 1.35rem; + } + + .workbench-inspector { + padding: 1rem; + } + + .workspace-grid-data { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .workspace-grid-analysis, + .workspace-grid-ai, + .workspace-grid-exports { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .workspace-grid-data > section:nth-child(3) { + grid-column: auto; + } + + .workbench-main .map-container, + .map-frame-surface .map-container { + height: calc(100vh - 18rem); + min-height: 36rem; + } + + .map-context-summary, + .dataset-role-summary-grid, + .layer-provenance-rail, + .guided-gis-steps, + .handoff-readiness-grid { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .map-inspection-surface { + grid-template-columns: minmax(22rem, 0.8fr) minmax(22rem, 1fr) minmax(22rem, 1fr); + } +} + +@media (min-width: 2200px) { + .workbench-layout { + grid-template-columns: 15rem minmax(0, 1fr) 26rem; + } + + .workbench-main { + padding: 1.2rem 1.65rem 1.5rem; + } + + .workspace-grid-data, + .workspace-grid-analysis, + .workspace-grid-ai, + .workspace-grid-exports { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } + + .workbench-main .map-container, + .map-frame-surface .map-container { + height: calc(100vh - 15.5rem); + min-height: 42rem; + } + + .map-workspace-shell .map-toolbar { + grid-template-columns: minmax(16rem, 1.35fr) minmax(12rem, 1fr) repeat(2, minmax(9rem, 0.85fr)) minmax(12rem, 1fr); + } +} + @media (max-width: 1180px) { .workspace-grid-data, .map-inspection-surface {