From 1ff27619500987b4d052c7dcefe5c5477588b507 Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 20 Jun 2026 01:18:27 +0200 Subject: [PATCH] Polish AI Labs mobile layout --- CHANGELOG.md | 8 +++ .../test_sprint75_ai_labs_mobile_polish.py | 37 ++++++++++++++ docs/CODEX_EXECUTION_LOG.md | 26 ++++++++++ docs/TODO.md | 1 + frontend/README.md | 2 + frontend/src/styles/app.css | 51 +++++++++++++++++++ 6 files changed, 125 insertions(+) create mode 100644 backend/tests/test_sprint75_ai_labs_mobile_polish.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c442df92..9e189007 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ # Changelog +## Sprint 75 AI Labs mobile visual polish (2026-06-20) + +- Tightened mobile Detection and Segmentation Lab model card, form and result-summary sizing. +- Added overflow wrapping for long model ids, source tile paths, mask paths and QA summary values. +- Kept result tables scroll-contained instead of allowing them to widen the workbench. +- Added static regression coverage for AI Labs mobile CSS and workflow markup contracts. +- No API contracts, migrations, backend behavior, provider fetching or AI model behavior changed. + ## Sprint 74 Data/Map mobile visual polish (2026-06-20) - Tightened mobile Data workspace upload form, file input and dataset action button sizing. diff --git a/backend/tests/test_sprint75_ai_labs_mobile_polish.py b/backend/tests/test_sprint75_ai_labs_mobile_polish.py new file mode 100644 index 00000000..526bf0e3 --- /dev/null +++ b/backend/tests/test_sprint75_ai_labs_mobile_polish.py @@ -0,0 +1,37 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[2] + + +def test_ai_labs_mobile_density_css_contracts() -> None: + css = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8") + + assert ".workspace-grid-ai .workspace-panel" in css + assert ".lab-block label" in css + assert ".lab-block input," in css + assert ".lab-block select" in css + assert ".lab-block .primary-action" in css + assert ".result-summary-card" in css + assert ".model-card strong" in css + assert ".table-scroll td" in css + assert ".table-scroll th" in css + assert "overflow-wrap: anywhere;" in css + assert "minmax(7.5rem, 1fr)" in css + + +def test_detection_and_segmentation_keep_ai_lab_workflow_markup() -> None: + detection_lab = (ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx").read_text( + encoding="utf-8" + ) + segmentation_lab = ( + ROOT / "frontend" / "src" / "components" / "segmentation" / "SegmentationLab.tsx" + ).read_text(encoding="utf-8") + + for source in (detection_lab, segmentation_lab): + assert 'className="model-list"' in source + assert "model-card" in source + assert 'className="lab-block"' in source + assert 'className="lab-form-grid"' in source + assert 'className="result-summary-card"' in source + assert 'className="table-scroll"' in source diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index 611c174c..749ea2e5 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -2794,3 +2794,29 @@ Limitations: Next recommended pass: - Continue with AI Labs mobile/density polish, especially detection and segmentation forms/tables. + +## Sprint 75 AI Labs mobile visual polish (2026-06-20) + +Changed: +- Added mobile-density CSS for Detection and Segmentation Lab model cards, run forms and result summaries. +- Added overflow wrapping for long model ids, source tile paths, mask paths and QA summary values. +- Kept AI result tables scroll-contained while reducing their mobile minimum width. +- Added `backend/tests/test_sprint75_ai_labs_mobile_polish.py`. +- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`. + +Tested: +- Red step: `python -m pytest backend/tests/test_sprint75_ai_labs_mobile_polish.py -q` failed on missing AI Labs mobile CSS contracts. +- `python -m pytest backend/tests/test_sprint75_ai_labs_mobile_polish.py backend/tests/test_sprint74_data_map_mobile_polish.py backend/tests/test_sprint72_mobile_overflow_hardening.py backend/tests/test_sprint62_frontend_visual_polish.py backend/tests/test_sprint30_workbench_components.py backend/tests/test_sprint8c_detection_visualization_qa.py backend/tests/test_sprint9_segmentation_foundation.py -q` (`30 passed`) +- `cd frontend && npm run typecheck` +- `cd frontend && npm run build` +- Local browser check against `http://127.0.0.1:5179` with live API proxy at a 390px viewport: AI Labs rendered 2 panels, 7 model cards, 6 lab blocks and 4 lab forms with no body-level horizontal overflow. +- Screenshot captured under `artifacts/sprint75-ai-labs-mobile-polish/`. + +Open: +- Run full readiness, redeploy Tower and verify live AI Labs mobile polish after deployment. + +Limitations: +- Frontend CSS polish only; no Detection/Segmentation workflow, API, persistence, migration, provider or AI/model changes. + +Next recommended pass: +- Continue with Export/System mobile-density polish, especially export action cards and provider capability lists. diff --git a/docs/TODO.md b/docs/TODO.md index 466f9e56..a220e757 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -64,6 +64,7 @@ This file now starts with the current implementation status. Older preparation/b - [x] Improve workbench shell visual polish, mobile navigation density and AI result readability. - [x] Improve Map workspace layer provenance, empty guidance and selected-feature summary readability. - [x] Add Data/Map mobile visual polish for upload forms, action grids and map toolbar density. +- [x] Add AI Labs mobile visual polish for model cards, lab forms and result tables. ## Sprint 8 status diff --git a/frontend/README.md b/frontend/README.md index cb91c61a..b2f5cf9f 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -6,6 +6,8 @@ The workbench now uses a task-based shell instead of a single long panel stack. Data and Map workspaces include mobile-density CSS for file inputs, dataset action buttons, map toolbar controls, range sliders and empty-map quick actions so narrow screens avoid accidental viewport overflow. +AI Labs uses the same mobile-density baseline for Detection and Segmentation model cards, run forms, QA/result summaries and scroll-safe result tables. This keeps long model ids, tile paths and artifact paths from widening the workbench on phones. + ## Scope implemented - API client layer (`src/services/api`) - Project and area list/create flows diff --git a/frontend/src/styles/app.css b/frontend/src/styles/app.css index e10d6080..e6bda2bf 100644 --- a/frontend/src/styles/app.css +++ b/frontend/src/styles/app.css @@ -867,6 +867,12 @@ section th { background: #f8fbf9; } +.table-scroll th, +.table-scroll td { + max-width: 18rem; + overflow-wrap: anywhere; +} + .workbench-inspector .job-result, .workbench-inspector pre { max-height: 16rem; @@ -1155,6 +1161,11 @@ button.entity-card { margin: 0.25rem 0 0; } +.model-card strong { + min-width: 0; + overflow-wrap: anywhere; +} + .model-card-ready { border-color: rgba(21, 128, 61, 0.24); } @@ -1233,10 +1244,12 @@ button.entity-card { } .result-summary-card p { + min-width: 0; margin: 0; color: #23423b; font-size: 0.86rem; line-height: 1.35; + overflow-wrap: anywhere; } .quality-summary-grid { @@ -1756,6 +1769,25 @@ button.entity-card { margin-top: 0.85rem; } +.workspace-grid-ai .workspace-panel { + min-width: 0; +} + +.lab-block label { + min-width: 0; +} + +.lab-block input, +.lab-block select { + width: 100%; + min-width: 0; +} + +.lab-block .primary-action { + width: fit-content; + max-width: 100%; +} + .lab-form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; @@ -2063,6 +2095,25 @@ button.entity-card { grid-template-columns: repeat(auto-fit, minmax(7.25rem, 1fr)); } + .result-summary-card { + grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr)); + } + + .workspace-grid-ai .model-list, + .workspace-grid-ai .lab-block { + gap: 0.55rem; + } + + .workspace-grid-ai .model-card, + .workspace-grid-ai .lab-block, + .workspace-grid-ai .result-summary-card { + padding: 0.68rem; + } + + .workspace-grid-ai .table-scroll table { + min-width: 36rem; + } + .dataset-action-button, .map-empty-action-grid button { min-height: 3rem;