From 000df670a316e538220c173d0364e935e0a20851 Mon Sep 17 00:00:00 2001 From: A Charlwood Date: Fri, 13 Feb 2026 16:42:23 +0000 Subject: [PATCH] Redesign CVMIS system --- .claude/settings.local.json | 7 +- AGENTS.md | 72 - CLAUDE.md | 179 +- Ralph/IMPLEMENTATION_PLAN.md | 210 +- Ralph/RALPH_PROMPT.md | 192 +- Ralph/completed/ref-boot-ecg.md | 359 ---- Ralph/guardrails.md | 109 +- Ralph/progress.txt | 78 + Ralph/refs/ref-banner-sidebar.md | 542 ----- Ralph/refs/ref-consultations.md | 207 -- Ralph/refs/ref-design-system.md | 158 -- Ralph/refs/ref-interactions.md | 163 -- Ralph/refs/ref-investigations-documents.md | 277 --- Ralph/refs/ref-medications.md | 270 --- Ralph/refs/ref-problems.md | 198 -- Ralph/refs/ref-referrals.md | 159 -- Ralph/refs/ref-summary-alert.md | 309 --- Ralph/refs/ref-transition-login.md | 212 -- References/concept.html | 1887 ----------------- Screenshot 2026-02-12 001926.png | Bin 67189 -> 0 bytes designs/01-the-compression.md | 522 ----- designs/02-the-dashboard.md | 624 ------ designs/03-the-observatory.md | 511 ----- designs/04-the-dosage.md | 724 ------- designs/05-the-depth-stack.md | 851 -------- designs/06-the-pipeline.md | 672 ------ designs/07-the-clinical-record.md | 1127 ---------- goal.md | 1127 ---------- .../ACCESSIBILITY.md | 111 - .../DESIGN-SYSTEM-TEMPLATE.md | 577 ----- .../MOTION-SPEC.md | 72 - .../RESPONSIVE-DESIGN.md | 90 - .../bencium-innovative-ux-designer/SKILL.md | 718 ------- src/index.css | 4 +- tailwind.config.js | 4 +- 35 files changed, 529 insertions(+), 12793 deletions(-) delete mode 100644 AGENTS.md delete mode 100644 Ralph/completed/ref-boot-ecg.md delete mode 100644 Ralph/refs/ref-banner-sidebar.md delete mode 100644 Ralph/refs/ref-consultations.md delete mode 100644 Ralph/refs/ref-design-system.md delete mode 100644 Ralph/refs/ref-interactions.md delete mode 100644 Ralph/refs/ref-investigations-documents.md delete mode 100644 Ralph/refs/ref-medications.md delete mode 100644 Ralph/refs/ref-problems.md delete mode 100644 Ralph/refs/ref-referrals.md delete mode 100644 Ralph/refs/ref-summary-alert.md delete mode 100644 Ralph/refs/ref-transition-login.md delete mode 100644 References/concept.html delete mode 100644 Screenshot 2026-02-12 001926.png delete mode 100644 designs/01-the-compression.md delete mode 100644 designs/02-the-dashboard.md delete mode 100644 designs/03-the-observatory.md delete mode 100644 designs/04-the-dosage.md delete mode 100644 designs/05-the-depth-stack.md delete mode 100644 designs/06-the-pipeline.md delete mode 100644 designs/07-the-clinical-record.md delete mode 100644 goal.md delete mode 100644 skills/bencium-innovative-ux-designer/ACCESSIBILITY.md delete mode 100644 skills/bencium-innovative-ux-designer/DESIGN-SYSTEM-TEMPLATE.md delete mode 100644 skills/bencium-innovative-ux-designer/MOTION-SPEC.md delete mode 100644 skills/bencium-innovative-ux-designer/RESPONSIVE-DESIGN.md delete mode 100644 skills/bencium-innovative-ux-designer/SKILL.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json index e0683ab..6784f0f 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -23,7 +23,12 @@ "mcp__playwright__browser_evaluate", "Bash(git add:*)", "Bash(git commit -m \"$\\(cat <<''EOF''\nTask 4: Rebuild PatientBanner with premium fonts, tooltip, and animations\n\n- Replace font-inter with font-ui \\(Elvaro Grotesque\\) throughout banner\n- Add custom NHSNumberWithTooltip with Framer Motion animated reveal\n- Add AnimatePresence crossfade between full/condensed banner states\n- Animate mobile overflow menu enter/exit\n- Add SkipButton to App.tsx for boot/ECG phase skip\n- Add shadow-pmr-banner, focus ring styles, prefers-reduced-motion support\n- Fix mobile banner to use patient data instead of hardcoded values\n\nCo-Authored-By: Claude Opus 4.6 \nEOF\n\\)\")", - "Bash(git commit:*)" + "Bash(git commit:*)", + "Bash(ls:*)", + "Bash(tasklist:*)", + "Bash(npx -y serve -l 3333 .)", + "Bash(npx serve:*)", + "Bash(timeout /t 3 /nobreak)" ] } } diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index efb7178..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,72 +0,0 @@ -# AGENTS.md - -This file provides guidance to AI agents (OpenCode, Claude Code, etc.) when working with code in this repository. - -## Project Overview - -Interactive CV/portfolio website for Andy Charlwood with a distinctive loading experience: terminal boot sequence → ECG canvas animation with name tracing. Built as a React SPA with TypeScript and Vite. - -## Commands - -- `npm run dev` — Start dev server (localhost:5173) -- `npm run build` — TypeScript compile + Vite production build -- `npm run typecheck` — TypeScript type checking only (`tsc --noEmit`) -- `npm run lint` — ESLint -- `npm run preview` — Preview production build - -No test framework is configured. - -## Architecture - -### Loading UI Flow - -`App.tsx` manages a `Phase` state (`'boot'` → `'ecg'`). Each phase renders exclusively: - -1. **BootSequence** — Terminal typing animation (~4s), green-on-black aesthetic -2. **ECGAnimation** — Canvas-based heartbeat animation (~5-6s) with letter tracing, background transitions from black to white - -Total boot-to-ECG completion time must be ≤10 seconds. - -### Key Patterns - -- **Canvas ECG**: `ECGAnimation.tsx` does imperative canvas drawing with requestAnimationFrame — flatline → 3 heartbeats (40px→60px→100px) → letter tracing → exit. - -### Path Aliases - -`@/` maps to `./src/` (configured in both `vite.config.ts` and `tsconfig.json`). - -### Styling - -Tailwind CSS with custom design tokens in `tailwind.config.js`: -- **Colors**: teal `#00897B` (primary), coral `#FF6B6B` (accent), ECG palette (green/cyan/dim) -- **Fonts**: Plus Jakarta Sans (primary), Inter Tight (secondary), Fira Code (mono/terminal) -- **Breakpoints**: xs 480px, sm 640px, md 768px, lg 1024px, xl 1280px - -### Type System - -All data types live in `src/types/index.ts`. Strict TypeScript — no `any` types. One component per file with typed props interfaces. - -## Guardrails - -- Boot sequence text and colors must match `References/concept.html` exactly (CLINICAL TERMINAL v3.2.1 format). -- ECG animation timing/amplitudes/color transitions must match the concept reference. -- When writing components with visual styling or animations, invoke the `frontend-design` skill first. - -## Available Skills - -This project has access to the following agent skills in `.agents/skills/`: -- **frontend-design** — Use for any visual styling or animation work - -## Project Structure - -``` -src/ -├── components/ # One component per file (PascalCase) -├── hooks/ # Custom hooks (camelCase, use* prefix) -├── lib/ # Utility functions -├── types/ # TypeScript interfaces -├── App.tsx # Phase manager (root component) -└── index.css # Global styles + Tailwind directives -Ralph/ # Implementation plan, guardrails, progress tracking -References/ # Source content (concept.html, ECGVideo/) -``` diff --git a/CLAUDE.md b/CLAUDE.md index 3a41114..f39e0d5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,12 +4,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -Interactive CV/portfolio for Andy Charlwood, presented as a premium clinical information system. The concept: *what if a GP surgery's patient record system were redesigned by a luxury product studio?* The structure and metaphor of a real clinical system (patient banner, sidebar navigation, record sections) — but elevated with refined typography, considered motion, and atmospheric depth. +Interactive CV/portfolio for Andy Charlwood, presented as a GP clinical record system. The concept: *what if a GP surgery's patient record system were redesigned by a luxury product studio?* The structure and metaphor of a real clinical system (tiles as record sections, status indicators, medication-style skill entries, alerts) — but elevated with refined typography, considered motion, and a modern light aesthetic. -**This is NOT a faithful NHS system clone.** It's a showcase portfolio that *evokes* the feel of clinical software while being distinctly beautiful. The clinical metaphor is the creative conceit; the execution should feel premium and elegant. +**This is NOT a faithful NHS system clone.** It's a showcase portfolio that *evokes* the feel of clinical software while being distinctly beautiful. The clinical metaphor is the creative conceit; the execution should feel premium and contemporary. Built as a React SPA with TypeScript and Vite. +**Reference design:** `References/GPSystemconcept.html` — the visual and structural target for the dashboard. + ## Commands - `npm run dev` — Start dev server (localhost:5173) @@ -24,22 +26,54 @@ No test framework is configured. ### Four-Phase UI Flow -`App.tsx` manages a `Phase` state (`'boot'` → `'ecg'` → `'login'` → `'pmr'`). Each phase renders exclusively: +`App.tsx` manages a `Phase` state (`'boot'` → `'ecg'` → `'login'` → `'dashboard'`). Each phase renders exclusively: 1. **BootSequence** — Terminal typing animation (~4s), green-on-black aesthetic. Fira Code font, matrix-green palette. **Locked — do not change.** 2. **ECGAnimation** — Canvas-based heartbeat animation with mask-based letter tracing. Background transitions from black to `#1E293B`. **Locked — do not change.** -3. **LoginScreen** — Animated login card on dark background. Types credentials at a natural pace, then presents an interactive "Log In" button for the user to click. This phase onward is open to design evolution. -4. **PMRInterface** — The main portfolio experience: patient banner + clinical sidebar + scrollable content views. +3. **LoginScreen** — Animated login card on dark background. Types credentials at a natural pace, then presents an interactive "Log In" button for the user to click. Login transitions to the dashboard. +4. **DashboardLayout** — The main portfolio experience: TopBar + Sidebar + scrollable tile-based dashboard. + +### Dashboard Layout (Post-Login) + +The dashboard uses a three-zone layout: + +``` +┌─────────────────────────────────────────────────────┐ +│ TopBar (fixed, 48px) — brand, search, session │ +├──────────┬──────────────────────────────────────────┤ +│ │ │ +│ Sidebar │ Card Grid (scrollable) │ +│ (272px) │ ┌─────────────────────────────────┐ │ +│ │ │ Patient Summary (full width) │ │ +│ Person │ ├────────────────┬────────────────┤ │ +│ Header │ │ Latest Results │ Repeat Meds │ │ +│ │ │ (KPIs) │ (Core Skills) │ │ +│ Tags │ ├────────────────┴────────────────┤ │ +│ │ │ Last Consultation (full width) │ │ +│ Alerts │ ├─────────────────────────────────┤ │ +│ │ │ Career Activity (full width) │ │ +│ │ ├─────────────────────────────────┤ │ +│ │ │ Education (full width) │ │ +│ │ ├─────────────────────────────────┤ │ +│ │ │ Projects (full width) │ │ +│ │ └─────────────────────────────────┘ │ +└──────────┴──────────────────────────────────────────┘ +``` + +**No view switching.** The dashboard is a single scrollable page of tiles. Users scroll to see all sections. Detail drill-down happens by expanding tiles in-place (accordion pattern). ### Key Patterns -- **Canvas ECG**: `ECGAnimation.tsx` does imperative canvas drawing with requestAnimationFrame — flatline → 3 heartbeats (40px→60px→100px) → mask-based letter tracing → exit. -- **Clinical sidebar navigation**: `ClinicalSidebar.tsx` provides hash-routed view switching with keyboard shortcuts (Alt+1-7, arrow keys, "/" for search). -- **Patient banner condensation**: `PatientBanner.tsx` uses IntersectionObserver via `useScrollCondensation` hook — full banner (80px) condenses to 48px on scroll. -- **Staggered entrance animations**: Framer Motion variants with sequenced delays (banner → sidebar → content). -- **View switching**: Instant — no crossfade or slide between views. Content fades in once on initial load only. -- **Expandable rows**: Consultation entries, medication rows, and problem entries expand in-place with height animation. -- **Responsive breakpoints**: Desktop (full sidebar + banner), Tablet (icon-only sidebar), Mobile (bottom nav bar). +- **Canvas ECG**: `ECGAnimation.tsx` does imperative canvas drawing with requestAnimationFrame — flatline → 3 heartbeats (40px→60px→100px) → mask-based letter tracing → exit. **Locked — do not change.** +- **TopBar**: `TopBar.tsx` — fixed at top, brand + search trigger + session info. Search bar triggers Command Palette on click/Ctrl+K. +- **Sidebar**: `Sidebar.tsx` — light background, contains PersonHeader (avatar, name, title, status, details), Tags, and Alerts only. Skills, Projects, Education are in the main content tiles. +- **Card Grid**: CSS Grid, 2 columns on desktop (gap 16px), 1 column on mobile. Tiles use a reusable `Card` component with consistent styling. +- **Tile Expansion**: Career Activity items, Project items, and Skill items expand in-place with height-only animation (200ms, ease-out). Single-expand accordion — only one item open at a time. +- **KPI Flip Cards**: Latest Results metrics flip on click to show explanation text. CSS perspective transform, 400ms. +- **Command Palette**: Ctrl+K opens a Spotlight-style search overlay. Fuzzy search via fuse.js. Keyboard navigation (arrow keys, Enter, Escape). +- **Staggered entrance**: TopBar slides down → Sidebar slides from left → Content fades in. Quick (200-300ms). +- **Expandable content**: Height-only animation, 200ms ease-out. Content grows/shrinks — no opacity fade. +- **Responsive breakpoints**: Desktop (full sidebar + 2-col grid), Tablet (collapsed/hidden sidebar + 1-col), Mobile (no sidebar, stacked tiles). ### Path Aliases @@ -49,14 +83,14 @@ No test framework is configured. All data types live in `src/types/index.ts` and `src/types/pmr.ts`. Strict TypeScript — no `any` types. One component per file with typed props interfaces. -## Design Direction: Clinical Luxury +## Design Direction: GP System Dashboard -The aesthetic direction is **"Clinical Luxury"** — the precision and information density of a medical records system, married to the refinement of high-end product design. Think Bloomberg Terminal redesigned by a Swiss design house. +The aesthetic direction is a **modern GP system dashboard** — the precision and information density of a medical records system, but with a light, contemporary, premium feel. Think: a healthcare SaaS product redesigned by a Swiss product studio. ### Tone - **Precise, not cold.** Every element has a reason. Spacing is generous but intentional. -- **Structured, not rigid.** The grid and hierarchy of clinical software, but with room to breathe. +- **Light, not washed out.** Warm sage background, clean white surfaces, deliberate color accents. - **Technical, not sterile.** Monospace data, status indicators, and coded entries create authentic texture. - **Elegant, not decorative.** No gratuitous ornament. Beauty comes from proportion, contrast, and type. @@ -64,100 +98,121 @@ The aesthetic direction is **"Clinical Luxury"** — the precision and informati Typography is the primary vehicle for premium feel. Avoid generic system fonts. -- **UI / Body — two candidates to evaluate (build with both, then choose):** - - **Elvaro Grotesque** (by TabojaStudio) — Modern grotesque sans-serif. 7 weights: Light (300), Regular (400), Medium (500), SemiBold (600), Bold (700), ExtraBold (800), Black (900). Also available as variable font. The "grotesque" classification carries institutional credibility (Helvetica/Akzidenz-Grotesk lineage) while feeling distinctly premium. Slightly condensed proportions suit data-dense UI. - - **Blumir** (by VisualCreativeStd) — Geometric-humanist hybrid, "blends geometric precision." 7 weights: Thin (100), ExtraLight (200), Light (300), Regular (400), Medium (500), SemiBold (600), Bold (700) — plus oblique variants for each. Also available as variable font. More refined/luxurious feel than Elvaro. - - Both fonts are sourced from Envato (licensed), stored locally in `Fonts/`. Web font files (WOFF/WOFF2) are available for both. **Do not use Inter, Roboto, or system defaults** — these read as generic. - - Font files for web: - - Elvaro: `Fonts/Elvaro Grotesque Sans Family/WOFF/TBJElvaro-*.woff2` - - Blumir: `Fonts/blumir-font-family/WOFF/Blumir-VF.woff2` (variable font) -- **Monospace / Data**: Geist Mono for timestamps, coded entries, registration numbers, and tabular data. This creates the "technical texture" that sells the clinical metaphor. +- **UI / Body:** + - **Elvaro Grotesque** (primary, `font-ui`) — Modern grotesque sans-serif. 7 weights (300-900). Institutional credibility with premium feel. Slightly condensed proportions suit data-dense UI. + - **Blumir** (alternative, `font-ui-alt`) — Geometric-humanist hybrid. Variable font (100-700). More refined/luxurious feel. + - Both fonts sourced from Envato (licensed), stored in `Fonts/`. **Do not use Inter, Roboto, DM Sans, or system defaults.** + - Font files: Elvaro `Fonts/Elvaro Grotesque Sans Family/WOFF/TBJElvaro-*.woff2`, Blumir `Fonts/blumir-font-family/WOFF/Blumir-VF.woff2` +- **Monospace / Data**: Geist Mono for timestamps, session info, GPhC number, dates, coded entries. Creates "technical texture." - **Terminal phase**: Fira Code — locked, do not change. -- **Type scale**: Keep it tight. Clinical systems use small text. Headings 15-18px, body 13-14px, labels 11-12px. Precision over drama. -- **Weight hierarchy**: Use weight (400/500/600/700) rather than size to establish hierarchy. Bold section headers, medium labels, regular body. +- **Type scale**: Tight. Headings 15-18px, body 12.5-14px, labels 10-12px. Precision over drama. +- **Weight hierarchy**: Use weight (400/500/600/700) rather than size to establish hierarchy. ### Color Palette -The palette anchors on NHS Blue as the institutional accent, with a predominantly dark sidebar + light content split that creates natural drama. +The palette anchors on teal as the primary accent, with a light sidebar + warm content background. -- **NHS Blue `#005EB8`** — The single strong accent color. Used for active states, links, buttons, interactive elements. This IS the brand color of the clinical metaphor. -- **Dark sidebar `#1E293B`** — Creates gravitas. The "serious software" feel comes from this dark chrome. -- **Patient banner `#334155`** — Slightly lighter than sidebar. The information-dense header bar. -- **Content background** — Not flat gray. Consider a very subtle warm tint, or a faint noise/grain texture overlay on `#F5F7FA` to add depth. The content area should feel like paper, not a spreadsheet. -- **Cards `#FFFFFF`** — Clean white with refined shadows (layered, not single-value). Cards should feel like they float slightly above the content surface. -- **Status colors**: Green `#22C55E`, Amber `#F59E0B`, Red `#EF4444` — used sparingly for traffic-light indicators. Always paired with text labels, never as sole signifier. -- **Text**: Primary `#111827`, Secondary `#6B7280`, Muted `#94A3B8`. Use the full range for hierarchy. +- **Teal `#0D6E6E`** — Primary accent. Active states, links, avatar gradient, interactive elements. Hover: `#0A8080`. Light: `rgba(10,128,128,0.08)`. +- **Background `#F0F5F4`** — Warm sage. The content area feels organic, not flat gray. +- **Sidebar `#F7FAFA`** — Very light. Right border `#D4E0DE` separates from content. +- **TopBar `#FFFFFF`** — White surface. Bottom border `#D4E0DE`. +- **Cards `#FFFFFF`** — White with shadow-sm and border-light. Hover deepens to shadow-md. +- **Status colors**: Success `#059669`, Amber `#D97706`, Alert `#DC2626`, Purple `#7C3AED` — each with light bg and border variants. Always paired with text labels. +- **Text**: Primary `#1A2B2A`, Secondary `#5B7A78`, Tertiary `#8DA8A5`. Use full range for hierarchy. +- **Borders**: Structural `#D4E0DE`, Cards/inner `#E4EDEB`. ### Shadows & Depth -Real clinical software is flat and border-heavy. This project should use shadows to create subtle layered depth: +Three-tier shadow system for layered depth: -- **Cards**: Multi-layered shadow — e.g., `0 1px 2px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.03)`. Gentle, not Material Design dramatic. -- **Sidebar**: Optional very subtle inner shadow or glow at the right edge where it meets content. -- **Patient banner**: Subtle drop shadow below to separate from content. -- **Hover states**: Cards may lift very slightly on hover (1-2px translate + shadow deepen). Keep it restrained. +- **Cards (resting)**: `0 1px 2px rgba(26,43,42,0.05)` — gentle, always present. +- **Cards (hover/interactive)**: `0 2px 8px rgba(26,43,42,0.08)` — slightly lifted. +- **Overlays (command palette, modals)**: `0 8px 32px rgba(26,43,42,0.12)` — clearly elevated. +- **Hover states**: Shadow deepens + border color strengthens. Subtle, not dramatic. ### Motion Motion should feel considered and premium, never flashy: -- **Entrance animations**: The PMR interface materializes in sequence — banner slides down → sidebar slides from left → content fades in. Quick (200-300ms) with easing. +- **Entrance animations**: Dashboard materializes in sequence — TopBar slides down → Sidebar slides from left → Content fades in. Quick (200-300ms) with easing. - **Login typing**: 80ms/char for username, 60ms/dot for password. Natural, readable pace. After typing completes, "Log In" button becomes interactive — user clicks to proceed. -- **Login transition**: On button click, card scales slightly and fades. Background carries over to PMR (both are `#1E293B`-derived). -- **View switching**: Instant, no transition between views. This preserves the "software application" feel. -- **Expandable content**: Height-only animation, 200ms ease-out. Content grows/shrinks — no opacity fade. -- **Hover states**: Subtle, immediate. Background color shifts, not transforms. Think: OS-level responsiveness. -- **Clinical alert**: Spring animation for entrance (Framer Motion `type: "spring"`). Dismiss: icon crossfade → height collapse. +- **Login transition**: On button click, card scales slightly and fades. Transition to dashboard layout. +- **Tile expansion**: Height-only animation, 200ms ease-out. Content grows/shrinks — no opacity fade. +- **KPI flip**: CSS perspective rotateY, 400ms ease-in-out. Click to flip, click to flip back. +- **Command palette**: Scale 0.97→1.0 + translateY entrance, 200ms. Backdrop fade. +- **Hover states**: Subtle, immediate. Border color shifts, shadow deepens. Think: OS-level responsiveness. - **`prefers-reduced-motion`**: All animations skip to final state. No exceptions. ### Spatial Composition -- **Generous but structured.** More whitespace than a real clinical system. Cards have 16-24px padding. Sections breathe. -- **Clear visual hierarchy.** Section headers (uppercase, small, tracked-out) → content. No ambiguity about what's a label vs. data. -- **Two-column summary grid** on desktop, single column on mobile. Cards span full width or half width — no orphan columns. -- **Tables** use proper `` markup with styled headers on a light gray background. Alternating row colors. This is where the clinical authenticity lives. +- **Generous but structured.** Cards have 20px padding. Tile grid has 16px gap. Sections breathe. +- **Clear visual hierarchy.** Card headers: uppercase, small (12px), tracked-out, secondary color with colored dot indicator. +- **Two-column grid** on desktop, single column on mobile. Full-width tiles span both columns. +- **Sidebar sections** separated by thin divider titles (10px, uppercase, tertiary, with line extending right). ### What Makes It Memorable -The distinctiveness comes from the *contrast between structure and polish*: -- A dark, serious sidebar next to warm, airy content -- Small, precise monospace data in a field of generous whitespace -- NHS blue punching through an otherwise muted palette -- The clinical metaphor itself — "Patient Record" for a CV is unexpected and charming +The distinctiveness comes from the *clinical metaphor applied to a modern interface*: +- A light, professional sidebar with clinical-style person header and alert flags +- Skills presented as "Repeat Medications" with frequency dosing (twice daily, when required) +- KPI metrics that flip to reveal explanations, like interactive test results +- Career history as a clinical timeline with color-coded entry types - The boot sequence → ECG → login flow is theatrical in a way that real clinical software never is +- Command palette (Ctrl+K) for searching records, like a clinical search tool ## Styling Tailwind CSS with custom design tokens in `tailwind.config.js`: -- **Color tokens**: All PMR-prefixed tokens in Tailwind config (`pmr-sidebar`, `pmr-banner`, `pmr-nhsblue`, etc.) -- **Fonts**: Configured as `font-inter`, `font-geist` (monospace) in Tailwind — these need updating when the primary UI font changes. +- **Color tokens**: PMR-prefixed tokens (`pmr-accent`, `pmr-bg`, `pmr-surface`, `pmr-sidebar`, `pmr-text-primary`, etc.) +- **Fonts**: `font-ui` (Elvaro Grotesque), `font-ui-alt` (Blumir), `font-geist` (Geist Mono), `font-mono` (Fira Code for terminal) - **Breakpoints**: xs 480px, sm 640px, md 768px, lg 1024px, xl 1280px -- **Border radius**: 4px default for cards/inputs (clinical precision). 12px exception for login card only. +- **Border radius**: 8px default for cards/tiles (`var(--radius)`). 6px for inner elements (`var(--radius-sm)`). 12px exception for login card and command palette. +- **Shadows**: `shadow-sm`, `shadow-md`, `shadow-lg` tokens matching three-tier system. +- CSS custom properties in `index.css` for both boot/ECG phase tokens and dashboard phase tokens. - Inline styles only for dynamic values that Tailwind can't express. -- CSS custom properties in `index.css` for both boot/ECG phase tokens and PMR phase tokens. ## Guardrails - **Boot sequence**: Text, colors, and timing must match `References/concept.html` exactly. **Do not modify.** - **ECG animation**: Timing, amplitudes, color transitions, and mask-based text reveal must match the concept reference. **Do not modify.** +- **Reference design**: `References/GPSystemconcept.html` is the visual and structural target for the dashboard. - **CV content**: Sourced from `References/CV_v4.md` — roles, dates, and achievement numbers must be accurate. - **Icons**: Via `lucide-react`, not unicode symbols. -- **Accessibility**: WCAG 2.1 AA compliance. Semantic HTML, ARIA attributes, keyboard navigation, `prefers-reduced-motion` support throughout. +- **Accessibility**: WCAG 2.1 AA compliance. Semantic HTML, ARIA attributes, keyboard navigation, `prefers-reduced-motion` support throughout. Status indicators always paired with text labels. - **No generic aesthetics**: Every design decision should feel intentional. If a component could appear in any random SaaS template, it needs more character. +- **Fonts**: Elvaro Grotesque (primary) or Blumir (alt). Never Inter, Roboto, DM Sans, or system defaults. DM Sans appears in the concept HTML as a placeholder only. ## Project Structure ``` src/ ├── components/ # One component per file (PascalCase) -│ └── views/ # PMR content views (SummaryView, ConsultationsView, etc.) +│ ├── tiles/ # Dashboard tile components (PatientSummaryTile, LatestResultsTile, etc.) +│ ├── views/ # Legacy PMR views (being replaced by tiles — may be referenced during transition) +│ ├── TopBar.tsx # Fixed top bar (brand, search trigger, session) +│ ├── Sidebar.tsx # Light sidebar (person header, tags, alerts) +│ ├── DashboardLayout.tsx # Main layout (topbar + sidebar + card grid) +│ ├── Card.tsx # Reusable card component with header +│ ├── CommandPalette.tsx # Ctrl+K search overlay +│ └── ... # Boot, ECG, Login (unchanged) ├── contexts/ # React contexts (AccessibilityContext) -├── data/ # Static data files (patient, consultations, medications, etc.) +├── data/ # Static data files +│ ├── patient.ts # Person details +│ ├── consultations.ts # Career roles (used in Last Consultation + Career Activity) +│ ├── medications.ts # Legacy skill data +│ ├── problems.ts # Achievements +│ ├── investigations.ts # Projects +│ ├── documents.ts # Education entries +│ ├── profile.ts # Personal statement +│ ├── tags.ts # Sidebar tags +│ ├── alerts.ts # Sidebar alert flags +│ ├── kpis.ts # KPI metrics for Latest Results +│ └── skills.ts # Skills with frequency/years (medication metaphor) ├── hooks/ # Custom hooks (camelCase, use* prefix) -├── lib/ # Utility functions +├── lib/ # Utility functions (search.ts for fuse.js) ├── types/ # TypeScript interfaces (index.ts, pmr.ts) ├── App.tsx # Phase manager (root component) └── index.css # Global styles + Tailwind directives Ralph/ # Implementation plan, guardrails, progress tracking -References/ # Source content (concept.html, CV_v4.md, ECGVideo/) +References/ # Source content (concept.html, GPSystemconcept.html, CV_v4.md) ``` diff --git a/Ralph/IMPLEMENTATION_PLAN.md b/Ralph/IMPLEMENTATION_PLAN.md index 3302409..f379feb 100644 --- a/Ralph/IMPLEMENTATION_PLAN.md +++ b/Ralph/IMPLEMENTATION_PLAN.md @@ -1,65 +1,201 @@ -# Implementation Plan — The Clinical Record (v3) +# Implementation Plan — GP System Dashboard Overhaul ## Project Overview -A premium portfolio CV presented as a clinical information system. The *structure* and *layout* come from GP software (EMIS Web, SystmOne) — patient banner, sidebar navigation, consultation journal, medications table, etc. — but the *execution* is **Clinical Luxury**: refined typography, layered shadows, generous spacing, premium fonts, atmospheric depth. - -**This is NOT a faithful NHS clone.** It's a showcase portfolio that *evokes* clinical software while being distinctly beautiful. - -**What's already done:** Data files (`src/data/*`), type system (`src/types/pmr.ts`), phase management (`App.tsx`), boot sequence, ECG animation, and design system foundation (Tailwind tokens, fonts, CSS variables). - -**What this plan builds:** The visual layer from login screen through to the full PMR interface — every component rebuilt to Clinical Luxury quality with the new premium font, refined surfaces, and user-interactive login. +Replace the "CareerRecord PMR" sidebar-nav + view-switching interface with a tile-based GP System dashboard. Reference design: `References/GPSystemconcept.html`. ## Quality Checks -Run after every task. All must pass before committing. +- `npm run typecheck` — zero errors +- `npm run lint` — pass (pre-existing AccessibilityContext warning OK) +- `npm run build` — must succeed -``` -npm run typecheck -npm run lint -npm run build -``` +## Important -## Reference Files +**This file is for progress tracking only.** For implementation detail on any task, read the referenced file in `Ralph/refs/`. Do NOT bloat this file with implementation notes — keep it lean. -Each task references files in `Ralph/refs/`. Read the referenced file(s) for full design specs, implementation patterns, and code snippets. The ref files ARE the spec — do not duplicate their content here. - -Always also read `Ralph/refs/ref-design-system.md` — it is the single source of truth for colors, typography, spacing, surfaces, and motion. - -Also read `CLAUDE.md` for font setup instructions (Elvaro Grotesque and Blumir candidates in `Fonts/` directory). +--- ## Tasks -- [x] **Task 1: Design system foundation.** Tailwind config, CSS variables, font loading. *(Completed — see progress.txt)* +### Phase 0: Foundation -- [x] **Task 1b: Boot sequence and ECG animation.** *(Completed and locked — do not modify)* +#### Task 1: Update design tokens and Tailwind config +> Detail: `Ralph/refs/ref-01-design-tokens.md` +- [ ] Update CSS custom properties in `src/index.css` (new palette, shadows, layout vars) +- [ ] Update `tailwind.config.js` (colors, shadows, borders, radius) +- [ ] Keep boot/ECG/login tokens unchanged +- [ ] Run quality checks -- [x] **Task 2: Set up premium font and update Tailwind config.** Read `CLAUDE.md` (Typography section) and `Ralph/refs/ref-design-system.md`. Load both candidate fonts from `Fonts/` directory (Elvaro Grotesque WOFF2 files and Blumir variable font WOFF2). Add `@font-face` declarations in `src/index.css`. Update Tailwind config to add `font-ui` family pointing to the chosen font (start with Elvaro, can be swapped later). Replace `font-inter` references in Tailwind config with `font-ui`. Ensure Geist Mono remains the monospace font. Keep Fira Code for boot/ECG phases only. +#### Task 2: Create new data files and update types +> Detail: `Ralph/refs/ref-02-data-types.md` +- [ ] Create `src/data/profile.ts` (personal statement) +- [ ] Create `src/data/tags.ts` (sidebar tags) +- [ ] Create `src/data/alerts.ts` (sidebar alert flags) +- [ ] Create `src/data/kpis.ts` (Latest Results metrics) +- [ ] Create `src/data/skills.ts` (skills with medication frequency + years) +- [ ] Update `src/types/pmr.ts` (new interfaces) +- [ ] Run quality checks -- [x] **Task 3: Rebuild LoginScreen.** Read `Ralph/refs/ref-transition-login.md`. Key changes from prior version: (a) Typing speed is now **80ms/char** for username, **60ms/dot** for password — natural pace, not frantic. (b) After typing completes, the "Log In" button becomes **user-interactive** — the user clicks it to proceed. It is NOT auto-triggered. Button should have hover state, full opacity when ready, disabled/dimmed while typing. (c) Card shadow uses multi-layered shadow per design system. (d) Uses [UI font] for labels, Geist Mono for input fields. (e) `prefers-reduced-motion`: typing completes instantly, button is immediately interactive. +#### Task 3: Update CLAUDE.md for new architecture +- [x] Already completed during project setup (manual intervention 2026-02-13) -- [x] **Task 4: Rebuild PatientBanner.** Read `Ralph/refs/ref-banner-sidebar.md` (Patient Banner section). Full banner (80px) with surname-first format, demographic details, action buttons. Condensed banner (48px) via IntersectionObserver at 100px scroll. Mobile minimal banner with overflow menu. Uses [UI font] throughout. NHS Number tooltip: "GPhC Registration Number". +### Phase 1: Core Layout -- [x] **Task 4b: Fix PatientBanner scroll condensation.** Read `Ralph/refs/ref-banner-sidebar.md` (Patient Banner section + Implementation Patterns). The full 3-row banner (80px — name/status, demographics, contact) never displays because the IntersectionObserver sentinel is broken. The sentinel (`absolute top-0` with `h-0`) is inside a React fragment next to the sticky header — it positions relative to the viewport, and the `-100px` rootMargin means it's immediately "not intersecting", so the banner always shows as condensed. Fix: ensure the sentinel is placed in the document flow ABOVE the scrollable content area (not absolute-positioned inside the banner fragment), so it's naturally visible on load and only scrolls out of view when the user scrolls 100px. Verify that on page load the full banner displays, and after scrolling 100px it smoothly condenses to the single-row 48px layout. +#### Task 4: Build TopBar component +> Detail: `Ralph/refs/ref-03-topbar-sidebar.md` (TopBar section) +- [ ] Create `src/components/TopBar.tsx` +- [ ] Brand section (icon + name + version tag) +- [ ] Search bar (triggers command palette, not inline search) +- [ ] Session info (mono font, pill badge) +- [ ] Fixed position, 48px height, white bg, bottom border +- [ ] Run quality checks -- [x] **Task 5: Rebuild ClinicalSidebar.** Read `Ralph/refs/ref-banner-sidebar.md` (Left Sidebar + Navigation sections). CV-friendly labels: Summary, Experience, Skills, Achievements, Projects, Education, Contact. 220px fixed width. Header branding, search input, navigation items with exact states (default/hover/active), separator line, footer with session info. Tablet mode: 56px icon-only. Keyboard shortcuts: Alt+1-7, arrow keys, "/" for search. URL hash routing. +#### Task 5: Build new Sidebar — PersonHeader +> Detail: `Ralph/refs/ref-03-topbar-sidebar.md` (Sidebar PersonHeader section) +- [ ] Create `src/components/Sidebar.tsx` +- [ ] Avatar circle (52px, teal gradient, initials) +- [ ] Name, title, status badge with pulse dot +- [ ] Details grid (GPhC, Education, Location, Phone, Email, Registered) +- [ ] 272px width, light background, right border +- [ ] Run quality checks -- [x] **Task 6: Rebuild PMRInterface layout + Breadcrumb.** Read `Ralph/refs/ref-banner-sidebar.md` (PMRInterface Layout + Breadcrumb sections). Fixed sidebar + sticky banner + scrollable content on `#F5F7FA`. Create `Breadcrumb.tsx`. Interface materialization animations (banner → sidebar → content stagger). View switching is INSTANT. Mobile: bottom nav bar. Update ViewId type if needed. +#### Task 6: Build new Sidebar — Tags + Alerts +> Detail: `Ralph/refs/ref-03-topbar-sidebar.md` (Tags and Alerts section) +- [ ] Section title component (uppercase, divider line) +- [ ] Tags section (flex wrap pills, color variants) +- [ ] Alerts section (colored flag items with icons) +- [ ] Run quality checks -- [x] **Task 7: Rebuild SummaryView + Clinical Alert.** Read `Ralph/refs/ref-summary-alert.md`. Clinical Alert with spring animation entrance, acknowledge → checkmark → collapse sequence. Summary cards: Demographics (full-width key-value), Active Problems (traffic lights), Current Skills quick table, Last Consultation preview. 2-column grid desktop, single column mobile. Navigation links to other views. +#### Task 7: Build DashboardLayout and wire up App.tsx +> Detail: `Ralph/refs/ref-04-dashboard-layout.md` +- [ ] Create `src/components/DashboardLayout.tsx` +- [ ] Three-zone layout: TopBar (fixed) + Sidebar (fixed) + Main (scrollable card grid) +- [ ] Card grid: 2 columns desktop, 1 column <900px +- [ ] Framer Motion entrance animations (topbar → sidebar → content) +- [ ] Update App.tsx: replace PMRInterface with DashboardLayout in PMR phase +- [ ] Verify boot → ECG → login → dashboard transition works +- [ ] Run quality checks -- [x] **Task 8: Rebuild ConsultationsView.** Read `Ralph/refs/ref-consultations.md`. Reverse-chronological journal. Collapsed entries with date, org, role, key achievement. Expanded: H/E/P structure with coded entries. Height-only expand animation (no opacity fade). One expanded at a time. 3px left border color-coded by employer. Second clinical alert on first visit. +### Phase 2: Dashboard Tiles -- [x] **Task 9: Rebuild MedicationsView.** Read `Ralph/refs/ref-medications.md`. Three category tabs (Active/Clinical/PRN). Semantic `
` with sortable columns. Expandable prescribing history in Geist Mono. Status dots with text labels. Mobile: card layout. +#### Task 8: Build reusable Card component +> Detail: `Ralph/refs/ref-05-card-and-top-tiles.md` (Card section) +- [ ] Create `src/components/Card.tsx` +- [ ] Base card styling (white, border, radius 8px, shadow-sm, hover shadow-md) +- [ ] `full` variant (spans both grid columns) +- [ ] CardHeader sub-component (dot + title + optional right text) +- [ ] Run quality checks -- [x] **Task 10: Rebuild ProblemsView.** Read `Ralph/refs/ref-problems.md`. Two sections: Active Problems and Resolved Problems. Traffic light dots (8px, always with text labels). Code column in Geist Mono. Expandable rows with narrative + linked consultation navigation. Mobile: card layout. +#### Task 9: Build PatientSummary tile +> Detail: `Ralph/refs/ref-05-card-and-top-tiles.md` (PatientSummary section) +- [ ] Create `src/components/tiles/PatientSummaryTile.tsx` +- [ ] Full-width card, first in grid +- [ ] Personal statement from `src/data/profile.ts` +- [ ] Run quality checks -- [x] **Task 11: Rebuild InvestigationsView + DocumentsView.** Read `Ralph/refs/ref-investigations-documents.md`. Both views share the expandable-row pattern with tree-indented monospace content (box-drawing characters). Investigations: status badges (Complete/Ongoing/Live). Documents: type icons per document category. "View Results" button for PharMetrics only. Mobile: card layouts. +#### Task 10: Build LatestResults tile +> Detail: `Ralph/refs/ref-05-card-and-top-tiles.md` (LatestResults section) +- [ ] Create `src/components/tiles/LatestResultsTile.tsx` +- [ ] Half-width card, 2x2 metric grid +- [ ] Four KPI metric cards with colored values +- [ ] Data from `src/data/kpis.ts` +- [ ] Run quality checks -- [x] **Task 12: Rebuild ReferralsView (Contact).** Read `Ralph/refs/ref-referrals.md`. Clinical referral form with priority radio buttons (Urgent/Routine/Two-Week Wait with tongue-in-cheek tooltips). Form validation, reference number generation, success state. Direct contact table below form. +#### Task 11: Build CoreSkills tile ("Repeat Medications") +> Detail: `Ralph/refs/ref-05-card-and-top-tiles.md` (CoreSkills section) +- [ ] Create `src/components/tiles/CoreSkillsTile.tsx` +- [ ] Half-width card, next to LatestResults +- [ ] Skills listed as medications with frequency + years +- [ ] Data from `src/data/skills.ts` +- [ ] Run quality checks -- [x] **Task 13: Fuzzy search with fuse.js.** Read `Ralph/refs/ref-interactions.md` (Search section). Install fuse.js. Build search index from all content. Results dropdown grouped by section. Clicking a result navigates to section + expands matching item. Mobile: search at top of each view. +#### Task 12: Build LastConsultation tile +> Detail: `Ralph/refs/ref-06-bottom-tiles.md` (LastConsultation section) +- [ ] Create `src/components/tiles/LastConsultationTile.tsx` +- [ ] Full-width card +- [ ] Header info row (Date, Org, Type, Band) +- [ ] Role title + achievement bullet list +- [ ] Data from first entry in `src/data/consultations.ts` +- [ ] Run quality checks -- [x] **Task 14: Responsive design audit.** Read `Ralph/refs/ref-interactions.md` (Responsive Strategy section). Test all three breakpoints: Desktop (>1024px), Tablet (768-1024px), Mobile (<768px). Tables → card layouts on mobile. Bottom nav bar. Touch targets ≥48px. +#### Task 13: Build CareerActivity tile +> Detail: `Ralph/refs/ref-06-bottom-tiles.md` (CareerActivity section) +- [ ] Create `src/components/tiles/CareerActivityTile.tsx` +- [ ] Full-width card, two-column activity grid +- [ ] Merge roles + projects + certs + education into timeline +- [ ] Color-coded dots by entry type +- [ ] Run quality checks -- [x] **Task 15: Accessibility audit + final polish.** Read `Ralph/refs/ref-interactions.md` (Accessibility section). Semantic HTML, ARIA attributes, focus management, keyboard navigation, screen reader announcements, `prefers-reduced-motion` support, WCAG 2.1 AA contrast. Final visual consistency pass. +#### Task 14: Build Education tile +> Detail: `Ralph/refs/ref-06-bottom-tiles.md` (Education section) +- [ ] Create `src/components/tiles/EducationTile.tsx` +- [ ] Full-width card, below Career Activity +- [ ] Education entries from documents data +- [ ] Run quality checks + +#### Task 15: Build Projects tile +> Detail: `Ralph/refs/ref-06-bottom-tiles.md` (Projects section) +- [ ] Create `src/components/tiles/ProjectsTile.tsx` +- [ ] Full-width card, prominent presentation +- [ ] Status badges, project names, years, descriptions +- [ ] Data from `src/data/investigations.ts` +- [ ] Run quality checks + +### Phase 3: Interactions + +#### Task 16: Tile expansion system +> Detail: `Ralph/refs/ref-07-interactions.md` (Tile Expansion section) +- [ ] CareerActivity items expand to show full role detail +- [ ] Projects items expand to show methodology, tech stack, results +- [ ] CoreSkills items expand to show prescribing history +- [ ] Height-only animation (200ms, no opacity fade) +- [ ] Single-expand accordion +- [ ] Keyboard: Enter/Space to expand, Escape to collapse +- [ ] Run quality checks + +#### Task 17: KPI flip card interaction +> Detail: `Ralph/refs/ref-07-interactions.md` (KPI Flip section) +- [ ] LatestResults metrics flip on click +- [ ] Front: value + label. Back: explanation text +- [ ] CSS perspective flip (400ms) or instant swap with reduced motion +- [ ] One card flipped at a time +- [ ] Run quality checks + +#### Task 18: Build Command Palette +> Detail: `Ralph/refs/ref-07-interactions.md` (Command Palette section) +- [ ] Create `src/components/CommandPalette.tsx` +- [ ] Ctrl+K trigger + search bar click trigger +- [ ] Overlay with backdrop blur, ESC to close +- [ ] Fuzzy search via fuse.js (adapt `src/lib/search.ts`) +- [ ] Grouped results by section + Quick Actions +- [ ] Keyboard navigation (arrows, Enter, Escape) +- [ ] Run quality checks + +### Phase 4: Polish + +#### Task 19: Responsive design +> Detail: `Ralph/refs/ref-08-polish.md` (Responsive section) +- [ ] Desktop (>1024px): full sidebar + 2-column grid +- [ ] Tablet (768–1024px): collapsed/hidden sidebar + adapted grid +- [ ] Mobile (<768px): no sidebar, single-column tiles, simplified topbar +- [ ] Touch-friendly targets (48px+) +- [ ] Run quality checks + +#### Task 20: Accessibility audit +> Detail: `Ralph/refs/ref-08-polish.md` (Accessibility section) +- [ ] Semantic HTML (header, nav, main, article, section) +- [ ] Keyboard navigation (Tab, Enter/Space, Escape, Ctrl+K, arrows) +- [ ] ARIA (expanded, controls, labels, live regions, dialog) +- [ ] Focus management (trap in palette, visible rings, return focus) +- [ ] `prefers-reduced-motion` on all animations +- [ ] Color contrast verification +- [ ] Run quality checks + +#### Task 21: Clean up and final polish +> Detail: `Ralph/refs/ref-08-polish.md` (Cleanup section) +- [ ] Remove unused old components (PatientBanner, ClinicalSidebar, Breadcrumb, etc.) +- [ ] Remove unused hooks (useScrollCondensation if unused) +- [ ] Verify no dead imports +- [ ] Final visual review against concept HTML +- [ ] Run quality checks (clean build) diff --git a/Ralph/RALPH_PROMPT.md b/Ralph/RALPH_PROMPT.md index 13a75b6..21e48d9 100644 --- a/Ralph/RALPH_PROMPT.md +++ b/Ralph/RALPH_PROMPT.md @@ -2,77 +2,58 @@ You are operating inside an automated loop. Each iteration you receive fresh context - you have NO memory of previous iterations. Your only persistence is the filesystem. -You are implementing **Design 7: The Clinical Record** — a Patient Medical Record (PMR) system that presents Andy's CV as a clinician would view a patient record. This is a visual redesign rebuilding existing components to achieve absolute thematic fidelity to real NHS clinical software. +You are implementing **a GP System Dashboard** — a tile-based clinical record interface that presents Andy's CV as a GP surgery would display a patient record. The clinical metaphor lives in the structure (tiles as record sections, skills as "medications" with frequency, alerts, KPI metrics, career timeline) while the visual execution is modern and premium. **The Concept:** -The "patient" is Andy's career. Users navigate a genuine NHS clinical software interface (similar to EMIS Web, SystmOne, Vision) with a patient banner, sidebar navigation, consultation journal, medications table, clinical alerts, and a login sequence. The clinical metaphor lives in the LAYOUT and VISUAL PRESENTATION — the sidebar labels use CV-friendly terms (Experience, Skills, Achievements, Projects, Education, Contact) while each view is laid out like its clinical equivalent (consultation journal, medications table, problems list, etc.). - -**IMPORTANT — Sidebar Label Convention:** -The sidebar uses CV-intuitive labels, NOT clinical jargon. But each view's content is presented in the clinical format: -- **Summary** → Patient summary layout -- **Experience** (not "Consultations") → Consultation journal layout with History/Examination/Plan -- **Skills** (not "Medications") → Medications table layout with dosages/frequency -- **Achievements** (not "Problems") → Problems list layout with traffic lights -- **Projects** (not "Investigations") → Investigation results layout -- **Education** (not "Documents") → Attached documents layout -- **Contact** (not "Referrals") → Referral form layout +The "patient" is Andy's career. After a theatrical boot → ECG → login sequence, users see a dashboard with a light sidebar (person details, tags, alert flags) and a scrollable grid of tiles (Patient Summary, Latest Results, Repeat Medications/Skills, Last Consultation, Career Activity, Education, Projects). Tiles can be expanded for detail. A command palette (Ctrl+K) provides search. The reference design is `References/GPSystemconcept.html`. ## Your Task This Iteration -1. **Read the Design Guidance in the reference file** (REQUIRED for visual components): Each reference file in `Ralph/refs/` contains a "Design Guidance (from /frontend-design)" section at the bottom with pre-generated design direction, code patterns, and implementation details. You MUST read this section before writing code — it provides the aesthetic direction and code examples for the component. Do NOT invoke the `/frontend-design` skill at runtime — the guidance is already embedded in the ref files. +1. **Read the reference file for your task** (REQUIRED): Each task in `IMPLEMENTATION_PLAN.md` references a detail file in `Ralph/refs/`. You MUST read this file before writing code — it provides the full specification, CSS values, data sources, and component structure. -2. **Read the plan**: Open `IMPLEMENTATION_PLAN.md` and find the highest-priority unchecked item (`- [ ]`). Items are listed in priority order - pick the first unchecked one. +2. **Read the plan**: Open `IMPLEMENTATION_PLAN.md` and find the highest-priority unchecked item (`- [ ]`). Items are listed in dependency order — pick the first unchecked one. **The plan is for tracking only** — all implementation detail is in the referenced `Ralph/refs/` file. -3. **Read accumulated learnings**: Open `progress.txt` and read the "Codebase Patterns" section. This contains learnings from previous iterations about PMR design system, data architecture, animation approach, and clinical system authenticity. +3. **Read accumulated learnings**: Open `progress.txt` and read the "Codebase Patterns" section AND the most recent manual intervention entry. These contain critical context about the architecture, established patterns, and decisions from previous iterations. 4. **Read guardrails**: Open `guardrails.md` and read ALL guardrails. These are hard rules you MUST follow. Key guardrails include: - - Light-mode only (clinical systems don't have dark mode) - - Instant view switching (no animations between views) - - Proper semantic table markup for all data tables - - Traffic lights must always have text labels - - Exact NHS blue color (#005EB8) - - ECG must end with flatline (not fade to white) - - Login typing animation specifics - - Consultation History/Examination/Plan format - - Coded entries in [XXX000] format - - Sidebar labels are CV-friendly (Experience, Skills, etc.), NOT clinical jargon + - Light-mode only + - Teal accent `#0D6E6E` (not NHS Blue) for interactive elements + - 8px border-radius for cards (not 4px) + - Three-tier shadow system (sm/md/lg) + - Height-only tile expansion (no opacity fade) + - Skills frequency: user-specified values (Data Analysis="Twice daily", etc.) + - Sidebar contains ONLY PersonHeader + Tags + Alerts + - Elvaro Grotesque font (not DM Sans, Inter, or Roboto) + - Geist Mono for data/timestamps (not Fira Code in dashboard) -5. **Implement the item**: Complete the single task you selected. Keep changes focused - one task per iteration. Write production-quality React/TypeScript code that faithfully reproduces a clinical information system. This is a design showcase requiring absolute thematic fidelity. +5. **Implement the item**: Complete the single task you selected. Keep changes focused — one task per iteration. Write production-quality React/TypeScript code. - **IMPORTANT — Ref files are the source of truth, not existing code.** The current codebase contains errors and legacy patterns from earlier iterations. Do NOT treat the existing component structure, layout, or behaviour as authoritative. If the existing code does not match what the ref file specifies, **rebuild the component from the ref spec** rather than patching around the existing implementation. The ref files define the target; the existing code is just a starting point that may need to be replaced entirely. + **IMPORTANT — Ref files are the source of truth.** If existing code contradicts the ref file, rebuild from the ref spec. -6. **Run quality checks**: Execute the quality check commands listed in `IMPLEMENTATION_PLAN.md` under "Quality Checks". Fix any issues before proceeding. +6. **Run quality checks**: Execute `npm run typecheck`, `npm run lint`, `npm run build`. Fix any issues before proceeding. -7. **Visual Review** (Tasks 1b-11 only — skip for non-visual tasks like Task 1, 12-15): After quality checks pass, verify your work visually in the browser using the Playwright MCP browser tools: +7. **Visual Review** (for visual tasks): After quality checks pass, verify your work in the browser using Playwright MCP: a. Navigate to `http://localhost:5173` using `mcp__playwright__browser_navigate`. - b. **First load only**: The app plays a boot→ECG→login→PMR sequence (~15s). Use `mcp__playwright__browser_wait_for` with `time: 15` then take a snapshot. On subsequent navigations, the app stays in PMR phase — no waiting needed. - c. Navigate to the hash route for your task's view: - - Task 1b (Boot/ECG): Refresh page, screenshot during boot sequence, then again during ECG animation - - Task 2 (Login): Refresh page, wait ~8s (after boot+ECG), screenshot the login screen - - Task 3 (Banner): Any PMR view — review the patient banner at top - - Task 4 (Sidebar): Any PMR view — review left sidebar - - Task 5 (Layout/Breadcrumb): Any PMR view — review overall composition - - Task 6: `#summary` | Task 7: `#experience` | Task 8: `#skills` - - Task 9: `#achievements` | Task 10: `#projects` then `#education` | Task 11: `#contact` - d. Use `mcp__playwright__browser_snapshot` (accessibility tree) or `mcp__playwright__browser_take_screenshot` (visual) to capture the page, and compare against your reference file. - e. Check specifically: colors match spec, correct font (Inter vs Geist Mono), proper spacing, `1px solid #E5E7EB` borders, 4px border-radius, layout alignment, NHS blue `#005EB8`. - f. If discrepancies are found: fix them, re-run quality checks, take another screenshot to confirm. - g. Note the visual review outcome in your progress.txt entry (step 10). + b. **First load only**: The app plays boot→ECG→login (~15s). Use `mcp__playwright__browser_wait_for` with `time: 15`, then click the Log In button to reach the dashboard. On subsequent navigations, the app stays in dashboard phase. + c. Take a screenshot and compare against `References/GPSystemconcept.html` (open it in a separate tab if needed). + d. Check: colors match spec, correct font, proper spacing, borders, shadows, layout alignment, teal accent. + e. Fix discrepancies, re-run quality checks, re-screenshot. + f. Note the visual review outcome in progress.txt. -8. **Commit your changes**: Stage and commit all changes with a descriptive message referencing the task you completed. +8. **Commit your changes**: Stage and commit all changes with a descriptive message referencing the task. 9. **Mark the item complete**: In `IMPLEMENTATION_PLAN.md`, change the item from `- [ ]` to `- [x]`. 10. **Update progress.txt**: Append to the "Iteration Log" section with: - - Which task you completed - - Any learnings or codebase patterns discovered (add to "Codebase Patterns" section) - - Any issues encountered - - Design decisions made (if visual component) - - Visual review outcome (what was checked, any fixes made) + - Which task you completed + - Any learnings or codebase patterns discovered (add to "Codebase Patterns" section too) + - Any issues encountered + - Design decisions made + - Visual review outcome 11. **Commit the progress update**: Stage and commit the updated `IMPLEMENTATION_PLAN.md` and `progress.txt`. -12. **Recommend model for next iteration**: Look at the NEXT unchecked task in `IMPLEMENTATION_PLAN.md` (the one after the task you just completed). Assess its complexity and output a model recommendation on its own line: +12. **Recommend model for next iteration**: Look at the NEXT unchecked task. Output a model recommendation: ``` sonnet @@ -84,86 +65,81 @@ The sidebar uses CV-intuitive labels, NOT clinical jargon. But each view's conte opus ``` - **Use this decision framework:** - - **Use `sonnet`** for: configuration tasks, search/utility implementation, responsive fixes, accessibility audits, tasks with very prescriptive specs, tasks that are mostly wiring/plumbing - - **Use `opus`** for: visual component rebuilds that invoke /frontend-design (design quality matters), complex animation work, tasks requiring strong aesthetic judgment, tasks where the previous iteration left issues that need creative problem-solving - - **Default to `sonnet`** if unsure — it's cheaper and handles well-specified tasks fine - - If there IS no next task (you just completed the last one), skip this step + **Decision framework:** + - **Use `sonnet`** for: configuration tasks, data files, simple wiring, accessibility audits, tasks with very prescriptive specs + - **Use `opus`** for: visual component builds, complex animation work, tasks requiring aesthetic judgment, command palette, interaction design + - **Default to `sonnet`** if unsure -13. **Determine if another iteration is needed**: Review your work and the codebase. The project needs another iteration if ANY of these are true: - - Any task in the checklist is unchecked (`- [ ]`) or blocked (`- [B]`) - - Quality checks would fail (run them to verify) - - There are uncommitted changes - - progress.txt has open questions or guidance for "next iteration" - - The implementation doesn't fully satisfy the plan requirements - - You have lingering doubts about correctness or completeness +13. **Determine if another iteration is needed**: The project needs another iteration if ANY task is unchecked, quality checks fail, or there are uncommitted changes. -14. **Send completion signal ONLY if truly complete**: If and ONLY if the project definitely does NOT need another iteration — all tasks verified done, quality checks pass, no guidance for next iteration — output this exact signal on its own line: +14. **Send completion signal ONLY if truly complete**: If ALL tasks are verified done, quality checks pass, and no further work is needed: ``` COMPLETE ``` - DO NOT output this string if there's any chance another iteration is needed. When in doubt, do NOT send the promise — leave it for the next iteration to determine. + DO NOT output this string if there's any chance another iteration is needed. ## Critical Rules -- **ALWAYS read the "Design Guidance" section in the ref file before writing visual component code** — do NOT invoke /frontend-design at runtime (it's pre-baked into the ref files) -- **Do NOT invoke the /frontend-design skill** — the design guidance is already embedded in each ref file. Invoking it at runtime will consume your context and stall the iteration. -- **ALWAYS visually review visual components (Tasks 1b-11) in the browser** — use Playwright MCP tools to screenshot and verify against the spec before committing +- **ALWAYS read the ref file for your task before writing code** - **Only work on ONE task per iteration** -- **Always read progress.txt AND guardrails.md before starting** — previous iterations may have left important context -- **If a task is blocked or unclear**, document why in progress.txt and move to the next unchecked item +- **Always read progress.txt AND guardrails.md before starting** +- **Ref files are the spec — existing code is not** +- **The plan file is for tracking only** — do not add detail to it +- **Use TypeScript strictly** — no `any` types, proper interfaces +- **Follow project structure** — components in `src/components/`, tiles in `src/components/tiles/`, data in `src/data/` +- **Respect prefers-reduced-motion** — all animations must have instant fallbacks - **Keep commits atomic and well-described** -- **If quality checks fail, fix the issues before committing** -- **Ref files are the spec — existing code is not.** If the current implementation contradicts the ref file, rebuild from the ref spec. Do not preserve broken patterns just because they exist in the codebase. -- **The visual quality bar is HIGH** — this must look like real clinical software -- **Preserve clinical system authenticity** — instant navigation, proper tables, NHS blue, coded entries, traffic lights -- **Sidebar labels are CV-friendly** — Experience (not Consultations), Skills (not Medications), etc. -- **Use TypeScript strictly** — no `any` types, proper interfaces for all PMR data structures -- **Follow the established project structure** — components in `src/components/`, data in `src/data/`, types in `src/types/` -- **Respect prefers-reduced-motion** — animations must have instant fallbacks +- **If quality checks fail, fix before committing** +- **If a task is blocked**, document why in progress.txt and move to next ## Reference Files -Each task in the implementation plan references specific files in `Ralph/refs/`: -- `Ralph/refs/ref-boot-ecg.md` — Boot sequence + ECG animation improvements -- `Ralph/refs/ref-design-system.md` — Colors, typography, spacing, borders, motion -- `Ralph/refs/ref-transition-login.md` — ECG flatline + login sequence -- `Ralph/refs/ref-banner-sidebar.md` — Patient banner + sidebar + navigation -- `Ralph/refs/ref-summary-alert.md` — Summary view + clinical alert -- `Ralph/refs/ref-consultations.md` — Experience view (consultation journal layout) -- `Ralph/refs/ref-medications.md` — Skills view (medications table layout) -- `Ralph/refs/ref-problems.md` — Achievements view (problems list layout) -- `Ralph/refs/ref-investigations-documents.md` — Projects + Education views -- `Ralph/refs/ref-referrals.md` — Contact view (referral form layout) -- `Ralph/refs/ref-interactions.md` — Interactions, responsive, accessibility +Each task references a specific detail file in `Ralph/refs/`: + +| Tasks | Reference File | +|-------|---------------| +| Task 1 | `Ralph/refs/ref-01-design-tokens.md` | +| Task 2 | `Ralph/refs/ref-02-data-types.md` | +| Tasks 4-6 | `Ralph/refs/ref-03-topbar-sidebar.md` | +| Task 7 | `Ralph/refs/ref-04-dashboard-layout.md` | +| Tasks 8-11 | `Ralph/refs/ref-05-card-and-top-tiles.md` | +| Tasks 12-15 | `Ralph/refs/ref-06-bottom-tiles.md` | +| Tasks 16-18 | `Ralph/refs/ref-07-interactions.md` | +| Tasks 19-21 | `Ralph/refs/ref-08-polish.md` | + +Also reference: +- `References/GPSystemconcept.html` — Visual/structural target for the dashboard - `References/CV_v4.md` — Source CV content (roles, achievements, numbers, dates) +- `CLAUDE.md` — Project architecture, design direction, styling conventions -Read ONLY the referenced file(s) for each task. Do NOT read goal.md directly. +Read ONLY the referenced file(s) for your current task. Do not read all ref files at once. -## Design Document Highlights +## Design Highlights **Color Palette (Light-mode only):** -- Main content: `#F5F7FA` -- Cards: `#FFFFFF` -- Sidebar: `#1E293B` -- NHS blue: `#005EB8` -- Green (active): `#22C55E` -- Amber (alerts): `#F59E0B` +- Background: `#F0F5F4` (warm sage) +- Surface/cards: `#FFFFFF` +- Sidebar: `#F7FAFA` (very light) +- Accent: `#0D6E6E` (teal) +- Borders: `#D4E0DE` (structural), `#E4EDEB` (cards) +- Text: `#1A2B2A` (primary), `#5B7A78` (secondary), `#8DA8A5` (tertiary) +- Status: `#059669` (success), `#D97706` (amber), `#DC2626` (alert) **Typography:** -- Inter for general text -- Geist Mono for coded entries and data values +- Elvaro Grotesque (`font-ui`) for UI text +- Geist Mono (`font-geist`) for data, timestamps, coded entries +- Fira Code for boot/ECG terminal only + +**Layout:** +- TopBar: fixed, 48px, white, bottom border +- Sidebar: 272px, light, person header + tags + alerts +- Main: scrollable card grid, 2 columns desktop, 1 column mobile +- Cards: 8px radius, shadow-sm, border-light **Key Interactions:** -- Login sequence: typing username/password character-by-character -- Clinical alert: slides down, acknowledges with checkmark → collapse -- Consultation entries: expand/collapse with History/Examination/Plan -- Medications table: sortable columns, expandable prescribing history -- Sidebar: instant view switching, no animations - -**Responsive Strategy:** -- Desktop (>1024px): 220px sidebar with labels -- Tablet (768-1024px): 56px icon-only sidebar -- Mobile (<768px): Bottom navigation bar +- Tile expansion: height-only animation, 200ms, accordion +- KPI flip: CSS perspective 400ms, click to flip/unflip +- Command palette: Ctrl+K, fuzzy search, keyboard navigation +- Entrance: staggered topbar → sidebar → content diff --git a/Ralph/completed/ref-boot-ecg.md b/Ralph/completed/ref-boot-ecg.md deleted file mode 100644 index fa19e50..0000000 --- a/Ralph/completed/ref-boot-ecg.md +++ /dev/null @@ -1,359 +0,0 @@ -# Reference: Boot Sequence + ECG Animation - -> Covers the full pre-login flow: terminal boot → cursor transition → ECG heartbeat → name reveal → flatline. The flatline→login transition is covered in `ref-transition-login.md`. - ---- - -## Current Architecture - -Two components manage the pre-login flow: -- `src/components/BootSequence.tsx` → terminal text animation, ends with blinking cursor -- `src/components/ECGAnimation.tsx` → canvas-based heartbeat + name tracing + flatline + bg transition -- `App.tsx` phases: `boot → ecg → login → pmr` - -## What Needs to Change - -### 1. Boot Sequence — Clean Up for Easy Config - -**Problem:** Boot text lines are hardcoded as HTML strings with inline Tailwind classes. Adding/removing/reordering lines requires editing raw HTML. The `dangerouslySetInnerHTML` approach is fragile. - -**Fix:** Refactor to a clean config-driven structure: -```typescript -// Example config structure — easy to customize -const BOOT_CONFIG = { - header: { text: 'CLINICAL TERMINAL v3.2.1', style: 'bright' }, - lines: [ - { type: 'status', text: 'Initialising pharmacist profile...' }, - { type: 'separator' }, - { type: 'field', label: 'SYSTEM', value: 'NHS Norfolk & Waveney ICB' }, - { type: 'field', label: 'USER', value: 'Andy Charlwood' }, - { type: 'field', label: 'ROLE', value: 'Deputy Head of Population Health & Data Analysis' }, - { type: 'field', label: 'LOCATION', value: 'Norwich, UK' }, - { type: 'separator' }, - { type: 'status', text: 'Loading modules...' }, - { type: 'module', name: 'pharmacist_core.sys' }, - { type: 'module', name: 'population_health.mod' }, - { type: 'module', name: 'data_analytics.eng' }, - { type: 'separator' }, - { type: 'ready', text: 'READY — Rendering CV..' }, - ], - timing: { lineDelay: 220, holdAfterComplete: 400, fadeOutDuration: 800 }, -} -``` -- Each line type maps to a React component (not raw HTML) -- Colors remain: bright green `#00ff41`, dim green `#3a6b45`, cyan labels `#00e5ff` -- Staggered reveal timing stays the same (220ms per line) -- Font: Fira Code (this is the terminal phase, NOT the PMR — Fira Code is correct here) - -### 2. Cursor → Dot Transition - -**Problem:** The boot sequence ends with a blinking green block cursor (`.animate-blink`). The ECG animation starts with a glowing dot that appears at the far left of the screen. There's a visual disconnect — the cursor and dot don't connect. - -**Fix:** The blinking cursor at the end of boot should smoothly transition INTO the ECG's glowing trace dot: -- At end of boot, capture the cursor's screen position (x, y) -- Pass this position to ECGAnimation via props -- ECGAnimation starts with its glowing dot AT the cursor position -- The cursor stops blinking and morphs: block cursor → circular glow (scale down width, increase glow, ~300ms) -- The dot then begins moving rightward, drawing the flatline/heartbeat trace behind it -- This means the ECG trace starts at the cursor position, NOT the far left edge - -### 3. ECG Start Position - -**Problem:** Currently the ECG trace starts at x=0 (far left of viewport). The cursor ends somewhere in the middle-left of the screen. This means the dot "teleports" from cursor position to the left edge. - -**Fix:** The ECG animation should: -- Accept a `startPosition: { x: number, y: number }` prop from the boot sequence -- Begin the trace from that position -- The first section of trace is a flat line from the cursor position rightward -- Heartbeats begin after the first flat gap (same timing as now, just offset) -- The viewport scroll logic already handles the "head" position — just shift the world-space origin - -### 4. Text Reveal — Mask Technique - -**Problem:** The current ECGAnimation.tsx reveals letters by stroking them with progressive alpha (`letterProgress > 0.3` → fade in). This looks like letters fading in, not like the ECG line IS the letter shape. - -**Reference:** `ECGCombined.tsx` (Remotion version at project root) uses a superior technique: -- The actual text characters are pre-rendered on the canvas (stroke-only, no fill) -- A wipe mask follows the ECG trace head, revealing the text underneath -- The ECG trace line IS the path that forms each letter shape (via the `getYAtX` function which returns letter Y values when in text region) -- Connector lines between letters sit at the baseline -- The neon glow filter applies to both the trace and revealed text - -**What to adopt from ECGCombined.tsx:** -- The mask-based text reveal approach (the trace unveils pre-rendered text) -- The connector lines between letters at baseline -- The neon glow SVG filters (or canvas equivalents) -- The text mask brush that follows the trace head - -**What to KEEP from current ECGAnimation.tsx:** -- The character spacing (current `LETTER_W`, `LETTER_G`, `SPACE_W` values — preferred over ECGCombined.tsx spacing) -- The heartbeat waveform shape (`generateHeartbeatPoints`) -- The beat timing and amplitude escalation (0.3 → 0.55 → 0.85 → 1.0) -- The canvas rendering approach (not SVG — canvas is correct for this performance-sensitive animation) -- The viewport scrolling/camera logic -- The flatline draw phase -- The scanline and vignette effects -- The background color transition to `#1E293B` - -### 5. Text Rendering - -- The name is still "ANDREW CHARLWOOD" -- Letters are stroke-only (no fill) in neon green `#00ff41` -- Each letter shape is defined by the `ECG_LETTERS` point arrays (keep these) -- The trace line passes through each letter's shape points, making the ECG waveform form recognizable letter shapes -- Between letters, the trace returns to baseline with short connector segments -- Neon glow effect on both trace and revealed text - -## Transition to Login - -After the text is fully revealed and the flatline extends to the right edge, the flow continues as described in `ref-transition-login.md`: -1. Name holds with glow (300ms) -2. Glow fades, flatline extends right -3. Canvas fades to black (200ms) -4. Background transitions to dark blue-gray `#1E293B` (200ms) -5. Login card materializes - -## prefers-reduced-motion - -With reduced motion enabled: -- Boot text appears instantly (no stagger) -- Cursor appears immediately -- ECG animation is skipped entirely — transition straight from boot to login -- Or: show the final frame (name fully revealed, flatline) as a static image for 1 second, then proceed to login - -## Testing Checklist - -- [ ] Boot text renders correctly with all lines -- [ ] Blinking cursor visible at end of boot -- [ ] Cursor smoothly transitions to ECG dot (no teleport) -- [ ] ECG trace starts from cursor position -- [ ] Heartbeats render with increasing amplitude -- [ ] Name letters revealed via mask technique (not alpha fade) -- [ ] Connector lines between letters -- [ ] Neon glow on trace and text -- [ ] Flatline extends to right edge after name -- [ ] Background transitions to `#1E293B` -- [ ] Scanlines and vignette present -- [ ] Reduced motion: instant/static -- [ ] Mobile: scales correctly - ---- - -## Design Guidance (from /frontend-design) - -> Pre-baked design direction. Do NOT invoke `/frontend-design` at runtime — this section contains the output. - -### Aesthetic Direction: Authentic Clinical Terminal → Medical Monitor Realism - -This isn't "medical-themed" design — this IS medical equipment interfaces. Two distinct phases: -1. **Boot Terminal**: Authentic 1990s clinical system boot sequence (think legacy pharmacy dispensing systems, hospital terminal logins). CRT monitor aesthetic with phosphor green, scanlines, slight text glow. -2. **ECG Monitor**: Hospital bedside cardiac monitor realism. The heartbeat isn't decorative — it's a functioning waveform that becomes letterforms through technical precision. - -**Visual Signature**: The cursor-to-dot morphing transition. Most animations have discrete phases; this creates continuous material transformation — the blinking terminal cursor literally becomes the ECG trace point. It's the moment where "loading system" becomes "reading vital signs." - -### Boot Sequence — Type-Safe Config - -```typescript -type BootLineType = 'header' | 'status' | 'separator' | 'field' | 'module' | 'ready' - -interface BootLine { - type: BootLineType - text: string - label?: string - value?: string - style?: 'bright' | 'dim' | 'cyan' -} - -interface BootConfig { - header: string - lines: BootLine[] - timing: { - lineDelay: number - cursorBlinkInterval: number - holdAfterComplete: number - fadeOutDuration: number - } - colors: { - bright: string - dim: string - cyan: string - } -} -``` - -Component architecture: -- `` — renders individual line types with appropriate styling -- `` — separate component for cursor with ref exposure for position capture -- Config-driven rendering replaces hardcoded HTML - -Example config: -```typescript -const BOOT_CONFIG: BootConfig = { - header: 'CLINICAL TERMINAL v3.2.1', - lines: [ - { type: 'status', text: 'Initialising pharmacist profile...', style: 'dim' }, - { type: 'separator', text: '---', style: 'dim' }, - { type: 'field', label: 'SYSTEM', value: 'NHS Norfolk & Waveney ICB', style: 'cyan' }, - { type: 'field', label: 'USER', value: 'Andy Charlwood', style: 'bright' }, - // ... etc - ], - timing: { lineDelay: 220, cursorBlinkInterval: 530, holdAfterComplete: 400, fadeOutDuration: 800 }, - colors: { bright: '#00ff41', dim: '#3a6b45', cyan: '#00e5ff' } -} -``` - -Example BootLine component: -```typescript -function BootLine({ line }: { line: BootLine }) { - const colors = BOOT_CONFIG.colors - const color = line.style ? colors[line.style] : colors.dim - - if (line.type === 'field') { - return ( -
- {line.label?.padEnd(9)} - {line.value} -
- ) - } - - if (line.type === 'module') { - return ( -
- [OK] - {' '} - {line.text} -
- ) - } - - // ... other types -} -``` - -### Cursor → Dot Transition — Implementation - -```typescript -const [cursorPosition, setCursorPosition] = useState<{x: number, y: number} | null>(null) -const cursorRef = useRef(null) - -useEffect(() => { - if (cursorRef.current) { - const rect = cursorRef.current.getBoundingClientRect() - setCursorPosition({ - x: rect.left + rect.width / 2, - y: rect.top + rect.height / 2 - }) - } -}, [/* trigger when boot completes */]) - -// Pass to ECG: - -``` - -Morph animation: width 8px→0px, height 16px→6px, border-radius 0→50% (300ms ease-out). Simultaneously fade in ECG dot at same position. After morph complete, begin trace movement. - -### Canvas Mask Reveal — Implementation - -```javascript -// Pre-render text to offscreen canvas -const textCanvas = document.createElement('canvas') -const textCtx = textCanvas.getContext('2d') -textCtx.strokeStyle = lineColor -textCtx.lineWidth = 1.5 -textCtx.font = `bold ${fontSize}px Arial` -textLayout.forEach(item => { - textCtx.strokeText(item.char, item.centerX, baselineY) -}) - -// During animation loop: -ctx.save() - -// Create clipping path following trace head -ctx.beginPath() -ctx.rect(0, 0, headSX + 20, vh) // reveal up to head position + lead -ctx.clip() - -// Draw pre-rendered text through clip -ctx.drawImage(textCanvas, -viewOff, 0) - -ctx.restore() - -// Feathered leading edge: -const gradient = ctx.createLinearGradient(headSX - 30, 0, headSX, 0) -gradient.addColorStop(0, 'rgba(0,255,65,0)') -gradient.addColorStop(1, 'rgba(0,255,65,1)') -``` - -### Connector Lines Between Letters - -```javascript -const connectors: {startX: number, endX: number}[] = [] -for (let i = 0; i < textLayout.length - 1; i++) { - const curr = textLayout[i] - const next = textLayout[i + 1] - const endInset = CONNECTOR_INSETS[curr.char] || 0 - const startInset = CONNECTOR_INSETS[next.char] || 0 - connectors.push({ - startX: curr.endX - endInset, - endX: next.startX + startInset - }) -} - -// During draw: -connectors.forEach(conn => { - if (headWX > conn.startX) { - const connectorEndX = Math.min(conn.endX, headWX) - ctx.beginPath() - ctx.moveTo(conn.startX - viewOff, baselineY) - ctx.lineTo(connectorEndX - viewOff, baselineY) - ctx.stroke() - } -}) -``` - -### Visual Enhancement Details - -**CRT Scanlines** (boot phase): -```css -.boot-scanlines { - position: absolute; - inset: 0; - background: repeating-linear-gradient( - 0deg, - rgba(0, 0, 0, 0.15) 0px, - transparent 1px, - transparent 2px, - rgba(0, 0, 0, 0.15) 3px - ); - pointer-events: none; - animation: scanline-drift 8s linear infinite; -} -``` - -**Phosphor Glow** (terminal text): -```css -.terminal-text { - text-shadow: - 0 0 4px currentColor, - 0 0 8px currentColor, - 0 0 12px rgba(0, 255, 65, 0.3); -} -``` - -**ECG Neon Glow** (canvas — multi-layer): -- Primary trace: 2px solid line -- Glow layer 1: 6px @ 25% opacity + shadowBlur 14px -- Glow layer 2: Inner 3px core for sharpness -- Text: Same multi-layer glow approach - -**Background Transition** (smooth RGB interpolation): -```javascript -const bgProgress = (elapsed - flatlineStartTime) / BG_TRANSITION -ctx.fillStyle = `rgb( - ${Math.round(0 + (30 * bgProgress))}, - ${Math.round(0 + (41 * bgProgress))}, - ${Math.round(0 + (59 * bgProgress))} -)` // black → #1E293B -ctx.fillRect(0, 0, vw, vh) -``` diff --git a/Ralph/guardrails.md b/Ralph/guardrails.md index b4ae737..e88dc26 100644 --- a/Ralph/guardrails.md +++ b/Ralph/guardrails.md @@ -5,8 +5,8 @@ Hard rules that MUST be followed in every iteration. Violating these will produc ## Design Direction ### When: Making ANY aesthetic decision -**Rule:** The direction is **Clinical Luxury** — the *structure* of clinical software (tables, status dots, coded entries, patient banner, sidebar) with *premium execution* (refined shadows, generous spacing, premium typography, atmospheric depth). This is NOT a faithful NHS clone. -**Why:** The previous "clinical utilitarian" direction produced generic, flat output. The new direction keeps the clinical metaphor but makes it beautiful. +**Rule:** The direction is **GP System Dashboard** — a tile-based clinical record system with a light, modern aesthetic. Teal accent (#0D6E6E), light sidebar (#F7FAFA), warm sage background (#F0F5F4), white card surfaces. The clinical metaphor lives in the STRUCTURE (tiles as "record sections", status indicators, medication-style skill entries, coded entries) — not in dark chrome or heavy clinical styling. +**Why:** The previous dark-sidebar PMR interface is being replaced with the lighter, tile-based GP System concept (`References/GPSystemconcept.html`). ## Design System Guardrails @@ -14,41 +14,66 @@ Hard rules that MUST be followed in every iteration. Violating these will produc **Rule:** Light-mode only. Do NOT add dark mode classes, `dark:` prefixes, or theme toggles. **Why:** The design direction is light-mode only. -### When: Setting border-radius on cards, inputs, or table elements -**Rule:** Use 4px border-radius (`rounded` in Tailwind). The only exception is the LoginScreen card which uses 12px. -**Why:** Clinical systems use minimal rounding. This precision is part of the Clinical Luxury feel. +### When: Setting border-radius on cards and tiles +**Rule:** Use 8px border-radius (var(--radius)) for cards and tiles. Use 6px (var(--radius-sm)) for inner elements (metric cards, activity items, tags). The only exception is the LoginScreen card which uses 12px, and the command palette which uses 12px. +**Why:** The GP System concept uses 8px radius, slightly more rounded than the old 4px clinical style, reflecting the lighter aesthetic. ### When: Using monospace/code font -**Rule:** Use Geist Mono (`font-family: 'Geist Mono', monospace`), NOT Fira Code, for coded entries, timestamps, clinical codes, and data values in the PMR interface. Fira Code is used in boot/ECG phases only. -**Why:** Geist Mono is the specified monospace font for the PMR interface. +**Rule:** Use Geist Mono (`font-family: 'Geist Mono', monospace`) for timestamps, session info, dates, GPhC number, and coded data values. Fira Code is used in boot/ECG phases only. +**Why:** Geist Mono is the specified monospace font for the dashboard interface. ### When: Choosing the UI text font -**Rule:** Use [UI font] — either Elvaro Grotesque or Blumir (see CLAUDE.md for setup). Do NOT use Inter, Roboto, or system defaults for the PMR interface. -**Why:** Premium typography is the primary vehicle for the luxury feel. Generic fonts undermine the entire direction. +**Rule:** Use Elvaro Grotesque (font-ui) as primary, Blumir (font-ui-alt) as alternative. Do NOT use Inter, Roboto, or system defaults. DM Sans appears in the concept HTML but is NOT the production font — use Elvaro Grotesque. +**Why:** Premium typography is the primary vehicle for the luxury feel. The concept HTML uses DM Sans as a placeholder; the production build uses the licensed premium fonts. -### When: Adding shadows to cards or panels -**Rule:** Use multi-layered shadows per the design system: `0 1px 2px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.03)`. Cards should feel like they float slightly above the content surface. Do NOT use flat, borderless cards or overly dramatic Material Design shadows. -**Why:** Layered shadows create the subtle depth that distinguishes Clinical Luxury from both flat clinical software and generic SaaS. +### When: Adding shadows to cards or tiles +**Rule:** Use the three-tier shadow system: +- `--shadow-sm`: `0 1px 2px rgba(26,43,42,0.05)` (default card state) +- `--shadow-md`: `0 2px 8px rgba(26,43,42,0.08)` (hover / interactive) +- `--shadow-lg`: `0 8px 32px rgba(26,43,42,0.12)` (command palette, overlays) +**Why:** Shadows create depth hierarchy. sm=resting, md=interactive, lg=overlay. ### When: Styling borders -**Rule:** All card and table borders must be `1px solid #E5E7EB` (gray-200). Keep borders on tables — they're authentically clinical. -**Why:** Borders provide clinical texture. Combined with shadows, they create the luxury-clinical contrast. +**Rule:** Use `1px solid var(--border-light)` (#E4EDEB) for card and tile borders. Use `1px solid var(--border)` (#D4E0DE) for structural borders (sidebar right edge, topbar bottom, section dividers). +**Why:** Two-tier border system: lighter for cards, slightly stronger for structural elements. -## Sidebar Label Convention +### When: Choosing accent/interactive colors +**Rule:** Use teal `#0D6E6E` (var(--accent)) for interactive elements: links, active states, avatar gradient, dots, hover highlights. Hover: `#0A8080`. Accent-light: `rgba(10,128,128,0.08)` for subtle backgrounds. +**Why:** Teal is the primary accent in the GP System concept. It replaces NHS Blue as the interactive color. -### When: Building or modifying sidebar navigation labels -**Rule:** Labels MUST be CV-friendly: Summary, Experience, Skills, Achievements, Projects, Education, Contact. Do NOT use clinical jargon (Consultations, Medications, etc.) as labels. The clinical metaphor lives in the LAYOUT of each view, not the labels. -**Why:** Non-clinical visitors should immediately understand what each section contains. +### When: Using status colors +**Rule:** Status colors: success=`#059669`, amber=`#D97706`, alert=`#DC2626`, purple=`#7C3AED` (education). Each with matching light/border variants. Always pair colored indicators with text labels. +**Why:** Traffic light convention. Color-only indicators violate WCAG. -## Navigation Guardrails +## Layout Guardrails -### When: Switching between sidebar views -**Rule:** View switching must be INSTANT. No crossfade, no slide animation, no opacity transition. -**Why:** Clinical systems use instant tab switching. This preserves the "application" feel. +### When: Building the dashboard layout +**Rule:** Three-zone layout: TopBar (fixed, 48px) + Sidebar (fixed left, 272px) + Main content (scrollable card grid). Main content has 24px-28px padding and card grid with 16px gap. Grid: 2 columns on desktop, 1 column below 900px. +**Why:** Matches the GP System concept layout structure. -### When: Building navigation -**Rule:** URL hash routing is required. Each view updates `window.location.hash`. -**Why:** Direct linking to specific views is required. +### When: Ordering tiles in the card grid +**Rule:** Tile order: Patient Summary (full) → Latest Results (half) + Repeat Medications (half) → Last Consultation (full) → Career Activity (full) → Education (full) → Projects (full). Full-width tiles span both columns. +**Why:** This ordering follows the concept layout with the user's addition of Patient Summary at the top. + +## Sidebar Guardrails + +### When: Building the sidebar +**Rule:** Sidebar contains ONLY: PersonHeader (avatar, name, title, status, details) → Tags → Alerts/Highlights. Active Projects, Core Skills, and Education are in the MAIN CONTENT as tiles, NOT in the sidebar. +**Why:** User explicitly requested moving Projects, Skills, and Education from sidebar to main dashboard tiles. + +## Interaction Guardrails + +### When: Expanding/collapsing tile content +**Rule:** Height animation ONLY (200ms, ease-out). Do NOT fade opacity on content. Single-expand accordion — only one item expanded at a time within a tile. +**Why:** Consistent expand/collapse behavior. Opacity fade was explicitly prohibited. + +### When: Building the command palette +**Rule:** Trigger via Ctrl+K or search bar click. Overlay with backdrop blur. ESC to close. Arrow key navigation. Fuzzy search via fuse.js. +**Why:** Matches concept interaction pattern. + +### When: Building KPI flip cards +**Rule:** Click to flip metric card (front=value, back=explanation). 400ms CSS perspective flip or instant swap with reduced motion. Only one card flipped at a time. +**Why:** User requested interactive KPI exploration with explanation text. ## Login Screen Guardrails @@ -58,32 +83,32 @@ Hard rules that MUST be followed in every iteration. Violating these will produc ## Component Guardrails -### When: Expanding/collapsing entries -**Rule:** Height animation ONLY (200ms, ease-out). Do NOT fade opacity on content. -**Why:** The spec explicitly states content grows/shrinks without opacity change. - ### When: Displaying traffic light status indicators **Rule:** Colored dots must ALWAYS have text labels. Never use color as the sole indicator. **Why:** WCAG — color cannot be the only means of communicating information. -### When: Rendering the clinical alert -**Rule:** Use Framer Motion `type: "spring"` animation for entrance (not ease-out). Amber colors: bg `#FEF3C7`, left border `#F59E0B`, text `#92400E`. -**Why:** Spring animation with slight overshoot makes alerts feel alive and demanding. +### When: Writing table or list markup inside tiles +**Rule:** Use semantic markup. Tables use `
`, ``, ``, ``, `
`, `
`. Lists use `
    `/`
      ` with `
    1. `. No div-based tables. +**Why:** Screen readers require native semantics. -### When: Writing table markup -**Rule:** Use semantic ``, ``, ``, ``, `
      `, `
      `. No div-based tables. -**Why:** Screen readers require native table semantics. +### When: Using icons +**Rule:** Use `lucide-react` icons only. No unicode symbols, no inline SVG copied from external sources. Exception: the concept's SVG icons should be converted to their lucide-react equivalents (e.g., concept's house icon → `Home` from lucide-react). +**Why:** Consistent icon system, tree-shakeable, accessible. ## Data Guardrails ### When: Displaying CV content -**Rule:** All data must come from `src/data/*.ts` files. Do NOT hardcode content in components or change any numbers/dates. -**Why:** Data has been validated against CV_v4.md. +**Rule:** All data must come from `src/data/*.ts` files. Do NOT hardcode content in components or change any numbers/dates. New data files (profile.ts, tags.ts, alerts.ts, kpis.ts, skills.ts) must be accurate to CV_v4.md. +**Why:** Data has been validated against CV_v4.md. Single source of truth. + +### When: Building the "Repeat Medications" (skills) tile +**Rule:** Use the exact frequencies specified by the user: Data Analysis="Twice daily", Power BI="Once weekly", Python="Daily", SQL="Daily", JavaScript/TypeScript="When required". Include "years of experience" like "length of time on medication". +**Why:** User explicitly specified these frequency values for the medication metaphor. ## Visual Review Guardrails ### When: Completing any visual task -**Rule:** After quality checks, open `http://localhost:5173` via Playwright MCP tools (`mcp__playwright__browser_navigate`, `mcp__playwright__browser_take_screenshot`, `mcp__playwright__browser_snapshot`), take a screenshot, and compare against the ref file spec. Fix visual discrepancies. If browser tools are unavailable, note in progress.txt and proceed. +**Rule:** After quality checks, open `http://localhost:5173` via Playwright MCP tools, take a screenshot, and compare against `References/GPSystemconcept.html`. Fix visual discrepancies. If browser tools are unavailable, note in progress.txt and proceed. **Why:** Code review alone cannot catch visual issues. ### When: Browser tools fail @@ -100,10 +125,10 @@ Hard rules that MUST be followed in every iteration. Violating these will produc **Rule:** All animations must respect `prefers-reduced-motion`. With reduced motion: all animations skip to final state instantly. **Why:** Accessibility requirement. -### When: Building visual components -**Rule:** Each ref file in `Ralph/refs/` contains a "Design Guidance" section with design direction and code patterns. Read it BEFORE writing code. Do NOT invoke `/frontend-design` at runtime. -**Why:** Design guidance is pre-baked to avoid context overflow. - ### When: Running quality checks **Rule:** Run `npm run typecheck`, `npm run lint`, and `npm run build` after EVERY task. Fix all errors before committing. **Why:** Build failures compound across iterations. + +### When: Referencing the concept design +**Rule:** The reference design is `References/GPSystemconcept.html`. Open it in a browser or read the HTML to understand the visual target. The concept is the LAYOUT reference; production fonts and some colors differ (see font and color guardrails). +**Why:** The concept HTML is the single source of truth for layout and spatial composition. diff --git a/Ralph/progress.txt b/Ralph/progress.txt index b32efa3..3ac061d 100644 --- a/Ralph/progress.txt +++ b/Ralph/progress.txt @@ -941,3 +941,81 @@ Do NOT invoke the `/frontend-design` skill at runtime — it was pre-run and the **ALL TASKS COMPLETE** — Implementation plan fully checked off (Tasks 1-15) +## Manual Intervention — 2026-02-13 +### Reason: Complete redesign — replacing CareerRecord PMR with GP System Dashboard +### Changes made: +- **IMPLEMENTATION_PLAN.md**: Completely rewritten with 21 new tasks for GP System dashboard overhaul +- **guardrails.md**: Completely rewritten for new design direction (teal palette, tile-based layout, 8px radius, new shadow system) +- **progress.txt**: This intervention entry added +- **CLAUDE.md**: Will be updated by Task 3 in the new plan (architecture, colors, components, styling) + +### Previous plan status: 15/15 tasks completed (all checked off) +### New plan: 21 tasks across 4 phases (Foundation → Core Layout → Dashboard Tiles → Interactions → Polish) + +### What's being replaced: +- `PatientBanner.tsx` → `TopBar.tsx` (white top bar with search and session info) +- `ClinicalSidebar.tsx` → `Sidebar.tsx` (light background #F7FAFA, person header, tags, alerts only) +- `PMRInterface.tsx` → `DashboardLayout.tsx` (topbar + sidebar + scrollable card grid) +- All 7 `views/*.tsx` files → Dashboard tile components in `src/components/tiles/` +- Color palette: dark sidebar (#1E293B) + NHS Blue (#005EB8) → light sidebar (#F7FAFA) + teal (#0D6E6E) +- Navigation: sidebar-nav view-switching → single scrollable dashboard with expandable tiles +- Patient banner scroll condensation → removed (no banner, just topbar) + +### What's preserved: +- Boot sequence (BootSequence.tsx) — LOCKED +- ECG animation (ECGAnimation.tsx) — LOCKED +- Login screen (LoginScreen.tsx) — unchanged +- Font setup: Elvaro Grotesque (primary UI), Blumir (alt), Geist Mono (data), Fira Code (terminal only) +- All data files in src/data/ — content unchanged, new data files added +- fuse.js dependency — reused for command palette search +- App.tsx phase management (boot → ecg → login → pmr) — pmr phase now renders DashboardLayout + +### Tasks in new plan: +Phase 0 — Foundation: +1. Update design tokens + Tailwind config +2. Create new data files + update types +3. Update CLAUDE.md for new architecture + +Phase 1 — Core Layout: +4. Build TopBar component +5. Build Sidebar — PersonHeader +6. Build Sidebar — Tags, Alerts +7. Build DashboardLayout + wire up App.tsx + +Phase 2 — Dashboard Tiles: +8. Build reusable Card component +9. Build PatientSummary tile +10. Build LatestResults tile +11. Build CoreSkills tile ("Repeat Medications") +12. Build LastConsultation tile +13. Build CareerActivity tile +14. Build Education tile +15. Build Projects tile + +Phase 3 — Interactions: +16. Tile expansion system +17. KPI flip card interaction +18. Build Command Palette + +Phase 4 — Polish: +19. Responsive design +20. Accessibility audit +21. Clean up + final polish + +### Context for next iteration: +- The reference design is `References/GPSystemconcept.html` — READ THIS before starting any visual task +- The old PMR components STILL EXIST in the codebase. Don't delete them yet — some expand/collapse patterns and data rendering can be reused inside tile expansion (Task 16). Cleanup happens in Task 21. +- Login screen still transitions to `#1E293B` background. The new dashboard has `#F0F5F4` background. The LoginScreen.tsx may need a background color update, or the transition can be handled in DashboardLayout's entrance animation. +- The concept HTML uses DM Sans font — this is a PLACEHOLDER. Production uses Elvaro Grotesque (font-ui). Do not switch to DM Sans. +- The concept's command palette has a comprehensive data model — use it as reference for building the palette in Task 18. +- Tile interactions (expansion, KPI flip) are in Phase 3. Tiles in Phase 2 should be built as static/display-only first, with data attributes or props that Phase 3 can hook into. + +### New guardrails added: +- Accent color: teal #0D6E6E (replacing NHS Blue #005EB8 as primary interactive color) +- Border radius: 8px for cards (was 4px) +- Shadow system: three-tier (sm/md/lg) replacing single pmr shadow +- Sidebar: light background, PersonHeader + Tags + Alerts ONLY (projects, skills, education moved to tiles) +- Layout: TopBar + Sidebar + Card Grid (replacing PatientBanner + ClinicalSidebar + view switching) +- Tile ordering: Patient Summary → Latest Results + Core Skills → Last Consultation → Career Activity → Education → Projects +- Skills frequency: user-specified values (Data Analysis=twice daily, etc.) + diff --git a/Ralph/refs/ref-banner-sidebar.md b/Ralph/refs/ref-banner-sidebar.md deleted file mode 100644 index 013d5e3..0000000 --- a/Ralph/refs/ref-banner-sidebar.md +++ /dev/null @@ -1,542 +0,0 @@ -# Reference: Patient Banner + Sidebar + Navigation - -> Extracted from goal.md — Patient Banner, Left Sidebar, and Navigation sections. These are the persistent UI chrome that defines the clinical system feel. - ---- - -## Patient Banner (Persistent Top Chrome) - -The patient banner is the most recognizable element of any PMR system. It spans the full viewport width above the main content area and provides constant demographic context. - -### Full Banner (80px height, visible at top of page) - -``` -+---------------------------------------------------------------------------+ -| CHARLWOOD, Andrew (Mr) Active (green dot) Open to opps. | -| DOB: 14/02/1993 | NHS No: 2211810 | Norwich, NR1 | -| 07795553088 | andy@charlwood.xyz [Download CV] [Email] [LinkedIn] | -+---------------------------------------------------------------------------+ -``` - -### Content Mapping - -| PMR Field | Actual Content | Notes | -|-----------|---------------|-------| -| Patient name | CHARLWOOD, Andrew (Mr) | Surname first, comma-separated — exactly as in clinical systems | -| DOB | 14/02/1993 | DD/MM/YYYY format (UK clinical standard) | -| NHS Number | 221 181 0 | Andy's GPhC registration number formatted like an NHS number (with spaces). Hover tooltip: "GPhC Registration Number" | -| GP Practice | Self-Referred | Tongue-in-cheek — Andy referred himself to this record | -| Address | Norwich, NR1 | Abbreviated postcode area | -| Phone | 07795553088 | Clickable (tel: link) | -| Email | andy@charlwood.xyz | Clickable (mailto: link) | -| Status | Active (green dot) | Like the "registered" status in a PMR | -| Badge | Open to opportunities | Styled as a clinical banner tag (blue background, white text, small pill shape) | - -### Action Buttons (top right of banner) - -| Button | PMR Equivalent | Action | -|--------|---------------|--------| -| Download CV | Print Summary | Downloads PDF version of CV | -| Email | Send Letter | Opens mailto: link | -| LinkedIn | External Link | Opens LinkedIn profile in new tab | - -Buttons are styled as small outlined rectangles with NHS blue text and 1px NHS blue border, 4px radius. On hover: filled NHS blue background with white text. - -### Condensed Banner (48px, sticky after scroll) - -When the user scrolls past 100px of content, the banner smoothly condenses to show only the essential information on a single line: - -``` -CHARLWOOD, Andrew (Mr) | NHS No: 2211810 | Active (green dot) [Download CV] [Email] -``` - -The condensed banner sticks to the top of the viewport (`position: sticky`) with a `z-index` above the content area but below modals/alerts. - ---- - -## Left Sidebar — Clinical Navigation - -The sidebar replicates the dark navigation panel found in EMIS Web and similar clinical systems. It provides category-based access to different "record views." - -**Width:** 220px (desktop), dark blue-gray (`#1E293B`) background. - -### Navigation Items - -**IMPORTANT:** Sidebar labels use CV-friendly terms, NOT clinical jargon. The clinical metaphor lives in the LAYOUT of each view, not the labels. - -| Icon | Label | View Layout Style | Description | -|------|-------|-------------------|-------------| -| `ClipboardList` | Summary | Patient summary screen | Demographics, active items, current skills, recent role | -| `FileText` | Experience | Consultation journal layout | Reverse-chronological journal of roles with H/E/P format | -| `Pill` | Skills | Medications table layout | Skills table with proficiency dosages and frequency | -| `AlertTriangle` | Achievements | Problems list layout | Challenges resolved and ongoing, with traffic lights | -| `FlaskConical` | Projects | Investigation results layout | Project outcomes with status badges | -| `FolderOpen` | Education | Attached documents layout | Certificates and qualifications | -| `Send` | Contact | Referral form layout | Contact/message form styled as clinical referral | - -### Styling - -- Each item: 44px height, 16px left padding, icon (18px, `lucide-react`) + label in [UI font] 500, 14px -- Default state: white text at 70% opacity, transparent background -- Hover state: white text at 100% opacity, background `rgba(255,255,255,0.08)` -- Active state: white text at 100%, NHS blue left border (3px), background `rgba(255,255,255,0.12)`, label in [UI font] 600 -- A thin horizontal separator line (`1px solid rgba(255,255,255,0.1)`) appears between "Summary" and "Consultations" (separating the overview from the detail views) - -### Sidebar Footer - -At the bottom of the sidebar, in small text ([UI font] 400, 11px, `#64748B`): -``` -Session: A.CHARLWOOD -Logged in: [current time] -``` -This updates with the actual current time on mount, reinforcing the "logged in" metaphor. - -### Sidebar Header - -At the top, above the navigation items, a small logo or system name: -``` -CareerRecord PMR -v1.0.0 -``` -In [UI font] 500, 13px, white at 50% opacity. Styled like clinical system branding that appears in the top-left of the navigation. - ---- - -## Navigation - -### Primary Navigation: Left Sidebar - -The sidebar is always visible on desktop — this is how clinical systems work. There is no floating nav, no hamburger menu on desktop, and no scroll-based navigation. The sidebar provides persistent, direct access to any record section. - -### Keyboard Shortcuts - -| Sidebar Item | View Layout | Shortcut | -|-------------|-------------|----------| -| Summary | Patient summary | `Alt+1` | -| Experience | Consultation journal | `Alt+2` | -| Skills | Medications table | `Alt+3` | -| Achievements | Problems list | `Alt+4` | -| Projects | Investigation results | `Alt+5` | -| Education | Attached documents | `Alt+6` | -| Contact | Referral form | `Alt+7` | - -### URL Hash Routing - -Each sidebar item updates the URL hash (`#summary`, `#experience`, `#skills`, `#achievements`, `#projects`, `#education`, `#contact`) for direct linking. On page load, the app reads the hash and navigates to the corresponding view. - -### Breadcrumb - -A breadcrumb appears at the top of the main content area: - -``` -Patient Record > Consultations > Interim Head, Population Health -``` - -The breadcrumb updates as the user navigates deeper (e.g., expanding a consultation). Clicking "Patient Record" returns to Summary. Clicking "Consultations" collapses any expanded entries and shows the full journal list. The breadcrumb is styled in [UI font] 400, 13px, gray-400, with chevron separators. - -### Secondary Navigation: Within-View Interactions - -- **Summary:** Clicking "View Full List" or "View Full Record" links navigates to the corresponding sidebar section. -- **Consultations:** Expand/collapse individual entries. "Linked consultations" in Problems view can deep-link to specific consultation entries. -- **Medications:** Category tabs (Active, Clinical, PRN) within the view. Click to expand prescribing history. -- **Problems:** Click to expand. "Linked consultations" navigate to Consultations view. -- **Investigations:** Click to expand results. -- **Documents:** Click to expand preview. -- **Referrals:** No sub-navigation. - ---- - -## Design Guidance - -### Aesthetic Direction - -**Clinical Luxury** — The patient banner and sidebar draw their *structure* from NHS clinical systems (PAS headers, EMIS Web navigation), but the *execution* is premium — refined typography, layered shadows, considered spacing. The clinical metaphor lives in the layout and conventions (surname-first, pipe separators, status dots); the luxury lives in the finish. - -- **Tone**: Precise, information-dense, and refined. Generous whitespace, layered shadows, and premium typography elevate what would otherwise be institutional UI. The clinical conventions (data density, pipe separators, monospaced identifiers, surname-first, green status dot) provide authentic texture. -- **Typography Discipline**: - - [UI font] at 600 weight for the patient name — the anchor element - - Geist Mono for structured identifiers (NHS Number, DOB) — monospaced data feels like it came from a database - - [UI font] at normal weight for demographic text - - The pipe character `|` as a data separator is a deliberate clinical convention - -### Design System Tokens - -| Token | Value | Usage | -|-------|-------|-------| -| NHS Blue | `#005EB8` | Primary accent, buttons, active states, borders | -| Banner Background | `#334155` (slate-700) | Patient banner background — exact EMIS Web header shade | -| Sidebar Background | `#1E293B` | Dark navigation panel | -| Content Background | `#F5F7FA` | Main content area | -| Border | `#E5E7EB` | 1px solid borders | -| Border Radius | `4px` | All UI elements | -| Green Status | `#22C55E` | Active status dot | -| Font Text | [UI font] | All text content (Elvaro or Blumir — see CLAUDE.md) | -| Font Data | `Geist Mono` | Monospaced identifiers | - -### Key Design Decisions - -1. **220px Sidebar Width**: Fixed, always visible on desktop. No hamburger menu. This is how clinical systems work — persistent direct access. - -2. **Alt+1-7 Keyboard Shortcuts**: Each sidebar item has a keyboard shortcut for power users. Arrow key navigation and `/` for search focus. - -3. **CV-Friendly Navigation Labels**: Not clinical jargon. The metaphor lives in the layout, not the labels: - - Summary (ClipboardList icon) - - Experience (FileText) - - Skills (Pill) - - Achievements (AlertTriangle) - - Projects (FlaskConical) - - Education (FolderOpen) - - Contact (Send) - -4. **Scroll-Triggered Banner Condensation**: - - Full banner: 80px height with three rows (name, demographics, contact/actions) - - Condensed: 48px sticky after 100px scroll, single line - - 200ms smooth transition - - IntersectionObserver for performance - -5. **Navigation Item States**: - - Default: white text at 70% opacity, transparent background - - Hover: white text at 100%, background `rgba(255,255,255,0.08)` - - Active: white text at 100%, 3px NHS blue left border, background `rgba(255,255,255,0.12)`, [UI font] 600 weight - -6. **Interface Materialization Animations** (PMRInterface): - - Patient banner slides down (200ms ease-out) - - Sidebar slides from left (250ms ease-out, 50ms delay) - - Content fades in (300ms, 100ms delay after sidebar) - - View switching is INSTANT — no crossfade or slide between views - -7. **Mobile Adaptations**: - - Banner collapses to minimal: `CHARLWOOD, A (Mr) | 2211810 | dot` - - Overflow menu for actions - - Bottom nav bar (56px height with safe area padding) - - Sidebar becomes icon-only (56px) with tooltips on tablet - -### Implementation Patterns - -#### PatientBanner Component Structure - -```tsx -// Main container with IntersectionObserver sentinel -<> -