FE-19: mobile-responsive board, toolbar, and dialog#944
Conversation
The fixed 16rem column width combined with horizontal-only scroll made the board view unusable below ~640px. Switch to a vertical stack with full-width lanes at ≤640px, relax the nested card-list max-height so the page scroller owns the scroll, and bump tap targets / input font-size to meet iOS guidelines. Part of FE-19 (#860).
TdDialog is the shared dialog primitive (CardModal, BoardSettingsModal, LabelManager, StarterPackCatalog, KeyboardHelp). On mobile a centered dialog with a 560px max-width left controls crowded and occasionally pushed footer actions off-screen when the iOS URL bar collapsed. Adopt a full-bleed layout at ≤640px with 100dvh height, stacked footer with 44px tap targets, and no rounding. Part of FE-19 (#860).
…bile Stack the toolbar vertically, wrap action buttons, and ensure every icon / text / primary button is at least 44×44px so touch interactions are reliable at iPhone SE widths. The primary Add Column / Add Card actions take the full row so they remain discoverable. Part of FE-19 (#860).
…flow Add a @mobile Playwright test that creates two columns, then asserts the second column is rendered below the first (vertical stack) and that neither the lanes nor the document itself exceed the viewport width. Part of FE-19 (#860).
Setting min-height alone on the back button left it ~24px wide because it wraps a raw SVG with no padding. Force inline-flex centering with a 44px min-width so the tap target is a full square, matching the touch-guideline minimum. Follow-up to self-review of FE-19 (#860).
Adversarial self-reviewFindings (addressed in a51fa6e):
Findings (no action needed, rationale below):
Desktop regression risk: All new styles are scoped under SignalR / realtime: The board fetches + SignalR subscribe in onMounted; vertical stack doesn't change DOM identity of columns/cards (same CLS / dvh gotcha: TdDialog uses |
There was a problem hiding this comment.
Code Review
This pull request introduces mobile responsiveness for the board view, including vertical stacking of lanes, full-screen dialogs, and accessible 44px tap targets. It also adds an E2E test to verify the vertical stacking behavior on small screens. Feedback includes ensuring the back button has a consistent minimum width for accessibility and using design tokens instead of hardcoded pixel values for font sizes to maintain consistency with the design system.
| .td-board-toolbar__icon-btn, | ||
| .td-board-toolbar__back-btn { | ||
| min-width: 44px; |
There was a problem hiding this comment.
The back-btn is essentially an icon button and should have a min-width of 44px to ensure a square and accessible tap target, consistent with the other icon buttons in the toolbar. Currently, it only has min-height set, which may result in a narrow hit area.
.td-board-toolbar__icon-btn,
.td-board-toolbar__back-btn {
min-width: 44px;
}
|
|
||
| .td-column-lane__card-input { | ||
| /* Prevent iOS zoom on focus: font-size >= 16px. */ | ||
| font-size: 16px; |
There was a problem hiding this comment.
Replace hardcoded 16px with the design token --td-font-lg (1rem / 16px) on the mobile .td-column-lane__card-input rule. Keeps iOS zoom-on-focus prevention while keeping typography under a single token.
- Add padding with env(safe-area-inset-*) so iOS notch/home-indicator does not cover dialog header or footer actions on full-bleed layout. - Declare max-height/height: 100vh before 100dvh so iOS Safari <= 15.4 (no dvh support) still gets full-viewport height instead of collapsing to content-sized dialog.
Round 2 adversarial reviewBot findings triaged
Own new findings (round 1 did not raise these)
CICI was 15/15 green at the start of round 2. After my two new commits ( VerdictReady to merge pending CI re-run. All bot findings addressed, two additional iOS-polish fixes applied. No pre-existing CI failures observed. Deferred items (tablet polish, secondary-view mobile sweep, touch DnD) remain correctly out of scope. |
Switch .td-dialog__footer from column-reverse to column on mobile so keyboard focus traverses buttons in the same order they appear on screen (WCAG 2.4.3 Focus Order). With column-reverse the primary action would render on top but focus still started on the secondary action below, creating a confusing mismatch for keyboard and assistive-tech users.
Round 2 adversarial review (fresh pass)Independent second look — overlaps with earlier round-2 comment are noted so this adds signal, not noise. Bot findings triaged
Own new findings
CIBefore this session: 14/15 green, E2E Smoke in progress on VerdictReady to merge once CI on |
Adversarial Code Review: PR #944 — FE-19 Mobile-Responsive Board, Toolbar, and DialogReviewer: Adversarial review (manual) Critical (P0)1.
|
| Bot Finding | Verdict |
|---|---|
Back button missing min-width: 44px for tap target |
Addressed by the PR — the mobile media query adds min-width: 44px to __back-btn. The bot may have reviewed an earlier revision. |
| ColumnLane hardcodes 16px font-size | False positive — the PR uses var(--td-font-lg) (the design token), not a hardcoded value. The bot may have been confused by the comment mentioning "16px". |
Action Items (blocking)
- P0: Fix
.td-dialog__footer > *to.td-dialog__footer > :slotted(*)so footer button sizing actually applies to slotted content. - P0: Either add
viewport-fit=coverto the viewport meta tag (with a full safe-area audit of other components) or remove theenv(safe-area-inset-*)references that are currently non-functional.
Action Items (recommended)
- P2: Consider
overflow-x: clipinstead ofoverflow-x: hiddenin BoardCanvas mobile styles to avoid the visible-becomes-auto overflow interaction.
Overall Assessment
Good PR with solid test coverage and thoughtful mobile patterns (dvh fallback, iOS zoom prevention, WCAG focus-order reasoning in the column-reverse comment). The two P0s are real issues that will silently fail in production on actual devices — the footer buttons will not get 44px sizing on any dialog, and the safe-area insets will always evaluate to 0.
TdDialog mobile footer: replace `> *` with `:deep(> *)` so the 44px tap-target and full-width rules actually reach slotted consumer content (Vue 3 scoped styles append [data-v-xxx] to `*`, which never matches slot children from other components). BoardCanvas mobile: change `overflow-x: hidden` to `overflow-x: clip` to avoid the CSS spec quirk where `overflow-y: visible` computes to `auto` when the cross-axis is `hidden`.
Update STATUS.md, IMPLEMENTATION_MASTERPLAN.md, TESTING_GUIDE.md, MANUAL_TEST_CHECKLIST.md, AUDIT.md, and HARDENING_AND_PERFORMANCE.md to reflect the mobile/security/legal/testing expansion wave: FE-19 mobile responsive, SEC-29 CSP style-src, legal drafts, TST-59 visual regression expansion, TST-60 E2E parallelization.
Closes #860 (partially — see Deferred below).
Summary
TdDialog(shared primitive powering CardModal, BoardSettingsModal, LabelManager, StarterPackCatalog, KeyboardHelp) becomes full-bleed at ≤640px with100dvhheight and stacked footer actions.@mobilePlaywright test asserts vertical-stack layout and zero horizontal document overflow on a two-column board.Surfaces covered
components/board/BoardCanvas.vue— vertical lanes, page-level scroll on mobilecomponents/board/ColumnLane.vue— full-width lanes, 16px input font to avoid iOS zoom, 44px buttonscomponents/board/BoardToolbar.vue— wrap actions, 44px tap targets, full-row primarycomponents/board/BoardActionRail.vue— 2-up wrap grid, 44px buttons, full-width primarycomponents/ui/TdDialog.vue— full-screen dialog on mobile (cascades to all TdDialog consumers)Already in place (no change needed)
ShellSidebar+AppShellalready ship a hamburger/off-canvas drawer with 44px nav items.CaptureModalalready had dedicated mobile styling.sm:640 / md:768 / lg:1024) already match the acceptance criteria.Deferred (follow-up)
The issue is sized at L (16h); this PR focuses on the highest-leverage board + dialog fixes. Out of scope for this slice:
CardItemis still the recommended path on mobile).Recommend filing a follow-up: "FE-19 follow-up: tablet + secondary-view mobile polish".
Test plan
npm run typecheck— cleannpm run lint— 6 pre-existing warnings, 0 new (limit 20)npx vitest --run— 2607 passed@mobilePlaywright project (Pixel 7 + iPhone 14) — run in CI / nightlyAdversarial notes
100dvh(dynamic viewport units) in TdDialog so footer doesn't hide under collapsing iOS Safari chrome; paired with100vhfallback.@media (max-width: 640px)so desktop ≥641px is untouched.style=bindings added (respecting SEC-29: Migrate CSP from unsafe-inline styles to external CSS #855).