# Responsive WebUI on Phone Viewports — Implementation Plan > **Parent spec:** Gitea issue #10 ("Make the server WebUI usable on > phone viewports") — verified root causes + acceptance criteria. > No separate spec file; the issue body is the spec. > > **For agentic workers:** REQUIRED SUB-SKILL: use the `implement` > skill to run this plan. Steps use `- [ ]` checkboxes for tracking. **Goal:** Make the server-rendered pages readable and operable on a ~390px phone viewport without changing the desktop (>=900px) layout. **Architecture:** CSS-only. Each of the four page templates owns its own ``/``** In `server/templates/my_cases.html`, replace the final rule + closing ``: ```html html.admin-view-off .admin-only { display: none !important; } ``` with: ```html html.admin-view-off .admin-only { display: none !important; } @media (max-width: 640px) { body { margin: 1em auto; } header { flex-wrap: wrap; gap: 0.6em; } .case-row, .case-list.has-bulk .case-row, html.admin-view-off .case-list.has-bulk .case-row { grid-template-columns: 1fr; } .case-row .actions { flex-wrap: wrap; } .case-row .actions button, .required-bar button, .bulk-bar button { min-height: 44px; } .case-row .actions .delete-btn, .case-row .actions .reopen-btn { min-width: 44px; min-height: 44px; justify-content: center; } } ``` - [ ] **Step 3: Verify its test passes** Run: `cargo test -p doctate-server --test responsive_test cases_list_has_viewport_and_media_query -j 4` Expected: PASS --- ## Task 4: case_recordings.html — viewport meta + player/touch breakpoint **Files:** - Modify: `server/templates/case_recordings.html:5,113` - [ ] **Step 1: Add the viewport meta tag** In `server/templates/case_recordings.html`, replace the charset line: ```html ``` with: ```html ``` - [ ] **Step 2: Append the `@media` block before ``** In `server/templates/case_recordings.html`, replace the final rule + closing ``: ```html .recording-head:has(.rec-delete-form.is-confirming) .player { visibility: hidden; } ``` with: ```html .recording-head:has(.rec-delete-form.is-confirming) .player { visibility: hidden; } @media (max-width: 640px) { body { margin: 1em auto; } header { flex-wrap: wrap; gap: 0.6em; } .player { width: 100%; justify-content: flex-start; } .player .seek { max-width: none; } .player .play { width: 44px; height: 44px; } .rec-delete-form .delete-btn { min-width: 44px; min-height: 44px; justify-content: center; } } ``` - [ ] **Step 3: Verify its test passes** Run: `cargo test -p doctate-server --test responsive_test case_recordings_has_viewport_and_media_query -j 4` Expected: PASS --- ## Task 5: case_page.html — viewport meta + reflow breakpoint **Files:** - Modify: `server/templates/case_page.html:6,350` Note: this template uses 8-space-indented, multi-line CSS and a self-closing `` style — match it. - [ ] **Step 1: Add the viewport meta tag** In `server/templates/case_page.html`, replace the charset line: ```html ``` with: ```html ``` - [ ] **Step 2: Append the `@media` block before ``** In `server/templates/case_page.html`, replace the final rule + closing ``: ```html html.admin-view-off .admin-only { display: none !important; } ``` with: ```html html.admin-view-off .admin-only { display: none !important; } @media (max-width: 640px) { body { margin: 1em auto; } .oneliner-input { min-width: 8em; } .doc-content { padding: 1em 1em; } .actions button { min-height: 44px; } .failure-banner dl.failure-details { grid-template-columns: 1fr; } } ``` - [ ] **Step 3: Verify its test passes** Run: `cargo test -p doctate-server --test responsive_test case_page_has_viewport_and_media_query -j 4` Expected: PASS --- ## Task 6: Full verification **Files:** (none — verification only) - [ ] **Step 1: Run the full responsive suite** Run: `cargo test -p doctate-server --test responsive_test -j 4` Expected: PASS — all 4 tests green. - [ ] **Step 2: Run the broader web/template tests for regressions** Run: `cargo test -p doctate-server --test web_test --test login_test --test case_page_test -j 4` Expected: PASS — viewport/`@media` additions are purely additive; no existing assertion changes. - [ ] **Step 3: cargo fmt** Run: `cargo fmt -p doctate-server` Expected: no diff in the new test file (it is already rustfmt-clean).