104 lines
7.5 KiB
Markdown
104 lines
7.5 KiB
Markdown
# Task: Portfolio UX Improvements — GP Clinical System Theme Polish
|
||
|
||
Implement 11 prioritised UX improvements to the portfolio site. This is an interactive CV/portfolio themed as a GP primary care clinical system (like EMIS Web / SystmOne). The site should feel like a real GP system but function as a portfolio.
|
||
|
||
**Important constraints:**
|
||
- Do NOT change the overall structure or architecture
|
||
- Preserve the GP clinical system theme — improvements should reinforce it, not break it
|
||
- Respect existing conventions: TypeScript strict, Tailwind + CSS custom properties, Framer Motion with `prefers-reduced-motion`
|
||
- Path alias: `@/*` → `src/*`
|
||
- Quality gates: `npm run lint && npm run typecheck && npm run build`
|
||
|
||
## Improvements (ordered by priority)
|
||
|
||
### 1. Restructure Profile Summary Text
|
||
**File:** `src/components/tiles/PatientSummaryTile.tsx` (or wherever the narrative renders)
|
||
**Problem:** The patient summary narrative is a dense ~80-word paragraph — a wall of text. It's the first substantive content visitors see and doesn't match the structured clinical aesthetic.
|
||
**Change:** Break into structured clinical-style data:
|
||
- Brief 1-2 sentence summary (like a presenting complaint)
|
||
- Key facts as labeled fields below: Specialisation, Current System, Population, Focus Areas
|
||
- Or collapse behind "Read more" with first sentence visible
|
||
- Must feel like GP system structured data, not a LinkedIn About section
|
||
|
||
### 2. Surface Impact Metrics on Project Cards
|
||
**File:** `src/components/tiles/ProjectsTile.tsx` (or the project card component)
|
||
**Problem:** `resultSummary` exists in the data (e.g., "14,000 patients identified", "£2.6M savings") but is not rendered on project card faces. Recruiters scan for numbers.
|
||
**Change:** Render `resultSummary` prominently on each project card — below the title, styled as a bold stat. If a project has no `resultSummary`, don't show a placeholder.
|
||
|
||
### 3. Add Prominent Contact/Download CV CTA
|
||
**Problem:** No visible "Get in touch" or "Download CV" button in the main content area. These actions only exist in the sidebar or command palette.
|
||
**Change:** Add a small, visible row of action buttons (Email, LinkedIn, GitHub, Download CV) in the Patient Summary section. Style them as GP system action buttons to reinforce the theme. Keep it compact — not a hero CTA, but unmissable.
|
||
|
||
### 4. Reduce Boot + Login Sequence Time
|
||
**Files:** `src/components/BootSequence.tsx`, `src/components/LoginScreen.tsx`
|
||
**Problem:** Boot (~6-8s) + Login (~4s) = ~10 seconds before content. Too slow for repeat visitors.
|
||
**Change:** Reduce `TYPING_SPEED` multiplier to ~1.2 (from 2). Add `sessionStorage` detection — if user has visited before in this session, auto-skip directly to dashboard. Ensure skip button still appears early for first-time visitors.
|
||
|
||
### 5. Resolve Last Consultation / Timeline Duplication
|
||
**Files:** `src/components/tiles/LastConsultationCard.tsx`, `src/components/tiles/TimelineInterventionsSubsection.tsx`
|
||
**Problem:** Current role appears twice — once as LastConsultationCard and again as first timeline accordion entry. Redundant.
|
||
**Change:** Differentiate LastConsultationCard as a summary-only card (role, org, band, date range, one-line summary) without the full bullet points. The full details should only appear in the timeline accordion. Add a "Current" badge to the first timeline accordion entry.
|
||
|
||
### 6. Fix Text-Tertiary Contrast Ratio
|
||
**File:** `src/index.css`
|
||
**Problem:** `--text-tertiary: #8DA8A5` on `--bg-dashboard: #F0F5F4` yields ~2.8:1 contrast, failing WCAG AA.
|
||
**Change:** Darken `--text-tertiary` to at least `#6B8886` (achieves ~4.5:1 on `#F0F5F4`). Verify the change looks good across dates, helper text, and monospace metadata.
|
||
|
||
### 7. Add Mobile Identity Bar
|
||
**Problem:** On mobile, no name or identity marker is visible without opening the drawer. Recruiters on mobile have no visual anchor.
|
||
**Change:** Add a compact identity bar at the top of mobile layout showing "CHARLWOOD, Andrew" and brief role title. Only visible on mobile (below `lg` breakpoint where sidebar is hidden). Style it like a GP system patient banner strip.
|
||
|
||
### 8. Simplify KPI Section Header Language
|
||
**File:** The KPI/metrics section component
|
||
**Problem:** "LATEST RESULTS (CLICK TO VIEW FULL REFERENCE RANGE)" is deep medical jargon that non-healthcare visitors won't understand.
|
||
**Change:** Change to "KEY METRICS" or "IMPACT HIGHLIGHTS". Update the helper text to "Select a metric to inspect methodology, impact, and outcomes" (if not already). Keep the excellent metric cards unchanged.
|
||
|
||
### 9. Add Detail Panel Exit Animation
|
||
**Files:** `src/components/DetailPanel.tsx`
|
||
**Problem:** Panel has `panel-slide-in` animation but closes instantly. `panel-slide-out` keyframe exists in CSS but is unused.
|
||
**Change:** Implement exit animation — either wire up the existing `panel-slide-out` keyframe via a closing state, or use Framer Motion's `AnimatePresence`. The panel should slide out before unmounting.
|
||
|
||
### 10. Fix marginBottom Typo
|
||
**File:** `src/components/tiles/LastConsultationCard.tsx` (around line 89)
|
||
**Problem:** `marginBottom: '1=px'` — typo, should be `'1px'` or appropriate value.
|
||
**Change:** Fix the typo. Check surrounding styles for the correct intended value.
|
||
|
||
### 11. Add Arrow Navigation to Desktop Projects Carousel
|
||
**File:** `src/components/tiles/ProjectsTile.tsx` — `ContinuousScrollCarousel` component (lines ~356–480)
|
||
**Problem:** The ContinuousScrollCarousel (desktop ≥1024px) auto-scrolls but offers no manual browsing.
|
||
**Change:**
|
||
- Add prev/next arrow buttons (ChevronLeft, ChevronRight from lucide-react) positioned absolutely at left/right edges, vertically centered
|
||
- Style following the existing FullscreenButton pattern: `var(--surface)` background, `var(--border)` border, opacity hover effect, subtle shadow
|
||
- Arrow click handler: jump one card width + gap = `((viewportWidth - 36) / 4) + 12` pixels
|
||
- Apply temporary CSS transition on the track (`transform 0.4s ease`) for smooth animated jump; remove transition after completion so rAF loop isn't fighting CSS
|
||
- Handle wrapping: keep offset within `[0, firstSetWidth)` using modulo
|
||
- Pause/resume: on arrow click set `isPausedRef = true`, clear existing timeout, start 6-second timeout to resume auto-scroll
|
||
- Existing hover pause/resume still works independently
|
||
- Rapid clicks: each click resets the 6s timeout; transition handles overlapping clicks by snapping to current offset
|
||
- Reduced motion: arrows still work (instant jump, no transition), auto-scroll stays disabled per existing logic
|
||
|
||
## Success Criteria
|
||
|
||
All of the following must be true:
|
||
- [ ] Profile summary is structured data, not a text wall — feels clinical
|
||
- [ ] Project cards display `resultSummary` when available
|
||
- [ ] Contact/Download CV actions are visible in the main content area
|
||
- [ ] Boot + login sequence completes in ~5 seconds or less for first visit; instant skip for return visitors
|
||
- [ ] LastConsultationCard is a distinct summary (no duplication with timeline)
|
||
- [ ] `--text-tertiary` passes WCAG AA contrast (4.5:1) on dashboard background
|
||
- [ ] Mobile shows identity/name without opening drawer
|
||
- [ ] KPI header uses plain language, not clinical jargon
|
||
- [ ] Detail panel has exit animation (slide out, not instant disappear)
|
||
- [ ] marginBottom typo is fixed
|
||
- [ ] Desktop projects carousel has prev/next arrow buttons
|
||
- [ ] Arrow buttons pause auto-scroll for 6s then resume
|
||
- [ ] `npm run lint` passes
|
||
- [ ] `npm run typecheck` passes
|
||
- [ ] `npm run build` passes
|
||
- [ ] No regressions — existing functionality preserved
|
||
|
||
## Status
|
||
|
||
Track progress here. Mark items complete as you go.
|
||
When all success criteria are met, print LOOP_COMPLETE.
|