6.0 KiB
6.0 KiB
Task: Fix Mobile Responsiveness for Small Viewport Widths (≤430px)
The portfolio website is broken on phones with viewport widths around 400px. Text overflows off-screen, elements are hidden behind overflow: hidden, and layout components are sized inappropriately for small screens.
Context
- Tech stack: React + TypeScript + Tailwind CSS + Framer Motion + D3
- Dev server:
npm run dev(localhost:5173) - Quality gates:
npm run lint && npm run typecheck && npm run build - Smallest configured breakpoint:
xs: 480pxin tailwind.config.js — there is no sub-480px handling - Key layout file:
src/components/DashboardLayout.tsxorchestrates all dashboard tiles - CSS media queries:
src/index.csscontains most custom responsive rules - Tailwind config:
tailwind.config.jsdefines breakpoints and theme
Target Viewports
Test and fix at these widths (all portrait orientation, 812px height):
- 320px — iPhone SE / smallest realistic phone
- 360px — Common Android (Samsung Galaxy S series)
- 375px — iPhone 12 mini / iPhone SE 3rd gen
- 390px — iPhone 14
- 400px — User's specific device (primary target)
- 414px — iPhone 8 Plus / larger phones
- 430px — iPhone 14 Pro Max
Known Issues (from codebase analysis)
Critical
- Sidebar must become a bottom nav bar at <600px — The current sidebar is a 304px-wide overlay on mobile, leaving only 96px for content at 400px. At viewport widths below 600px, replace the sidebar with a bottom navigation bar that:
- Collapsed state (default): A slim fixed bar along the bottom edge of the screen with icon-based navigation items (like a mobile tab bar / iOS-style bottom nav). Should not obscure content — main content area accounts for its height.
- Expanded state (on tap/click): Slides up as a drawer/sheet showing the full sidebar content (patient name, navigation links, etc.). Tapping the bar or a close affordance collapses it back down.
- The existing sidebar behavior for viewports ≥600px should remain completely unchanged.
- Use Framer Motion for the drawer slide animation, consistent with existing animation patterns.
- KPI grid forces 2 columns —
repeat(2, minmax(0, 1fr))creates cramped cards at small widths. Values use30pxfont. - Timeline text silently clipped —
overflow: hiddenon Card.tsx hides content with no visual indication (no ellipsis, no wrapping). - Project carousel cards too small — At 400px with 2 cards per view, each card is only ~194px wide.
Important
- Constellation graph — 520px height at <768px may be disproportionate; needs better sizing.
- No sub-480px breakpoint — The smallest Tailwind breakpoint is
xs: 480px, leaving 320-479px unhandled.
Minor
- Padding/spacing —
p-5(20px) main content +24pxcard padding eats significant space at 400px. - Detail panel header — Close button (44px) + title cramped at narrow widths.
- Skills/medications grid — May need column count reduction at small widths.
Requirements
- All text must be visible — no text clipped by
overflow: hiddenwithout ellipsis or wrapping. Truncated text needstext-overflow: ellipsiswith title attribute for accessibility. - All interactive elements must be reachable — nothing hidden off-screen or behind other elements.
- Touch targets — minimum 44x44px for interactive elements.
- Readable font sizes — minimum 12px body text, 14px primary content.
- No horizontal scroll — page must never scroll horizontally at any target viewport.
- Maintain visual identity — keep PMR aesthetic, teal/coral palette, existing design language. Adapt proportionally, don't radically redesign.
- Respect existing patterns — use Tailwind classes where possible, use existing CSS custom properties, follow project conventions.
Success Criteria
All of the following must be true:
npm run lintpasses with zero errorsnpm run typecheckpasses with zero errorsnpm run buildsucceeds- At 320px viewport: no horizontal scrollbar, all text readable, no content clipped without indication
- At 360px viewport: same as above
- At 375px viewport: same as above
- At 390px viewport: same as above
- At 400px viewport: same as above (primary target)
- At 414px viewport: same as above
- At 430px viewport: same as above
- At <600px: sidebar is replaced by a bottom nav bar with collapsed (tab bar) and expanded (drawer) states
- Bottom nav bar does not obscure page content in collapsed state (content has bottom padding/margin to account for it)
- Bottom nav drawer expands on tap and shows full navigation content
- Bottom nav drawer can be collapsed back down
- At ≥600px: existing sidebar behavior is completely unchanged
- KPI cards are readable with appropriate font sizing
- Timeline entries show full text or have proper ellipsis truncation
- Project carousel cards are adequately sized (consider 1 card per view if needed)
- Constellation graph fits within viewport without excessive scrolling
- Desktop/tablet layouts (768px+) remain unchanged and unbroken
Constraints
- Do NOT change boot sequence, ECG animation, or login screen (already handle small screens)
- Do NOT change D3 force simulation logic — only container sizing
- Do NOT add new npm dependencies
- Do NOT remove existing features or functionality
- Keep changes minimal and focused — fix responsiveness, don't redesign
- Preserve all existing breakpoint behavior for md (768px) and above
Visual Validation Method
Use Playwright MCP to:
- Navigate to
http://localhost:5173(dev server must be running) - Get past boot sequence + ECG + login to reach dashboard
- Set viewport to each target width × 812px height
- Take screenshots of dashboard at each viewport
- Visually inspect for: overflow, clipping, cramped text, unreachable elements
- Scroll through full page and verify no content is hidden
Status
Track progress here. When all success criteria are met, print LOOP_COMPLETE.