# Progress Log ## Codebase Patterns ### Project Structure - Components in `src/components/`, views in `src/components/views/` - Data files in `src/data/` — consultations.ts, medications.ts, problems.ts, investigations.ts, documents.ts, patient.ts - Types in `src/types/pmr.ts` (PMR interfaces) and `src/types/index.ts` (Phase type) - Hooks in `src/hooks/` — useScrollCondensation.ts, useBreakpoint.ts - Contexts in `src/contexts/` — AccessibilityContext.tsx - Path alias: `@/` maps to `./src/` ### Phase Management - App.tsx controls phase: 'boot' -> 'ecg' -> 'login' -> 'pmr' - BootSequence.tsx handles terminal animation - ECGAnimation.tsx handles heartbeat + letter tracing + flatline exit - LoginScreen.tsx bridges to PMRInterface.tsx ### Data Architecture (CORRECT — do not modify) - All data files are populated with accurate CV content from References/CV_v4.md - 5 consultation entries (roles), 18 medications (skills), 11 problems (achievements), 6 investigations (projects), 5 documents (education) - Types are properly defined in pmr.ts — Consultation, Medication, Problem, Investigation, Document, Patient, ViewId ### Design System Requirements (from ref-design-system.md) - Light-mode ONLY — no dark mode - NHS blue: #005EB8 (primary interactive) - Border radius: 4px for cards/inputs - Borders: 1px solid #E5E7EB on tables and cards, combined with multi-layered shadows for depth - Card shadows: 0 1px 2px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.03) - Table row height: 40px, card padding: 16-24px, main content padding: 24px - Fonts: [UI font] (Elvaro Grotesque or Blumir from Fonts/ dir), Geist Mono (coded entries, timestamps, data values) - Base spacing unit: 4px — generous but structured, more whitespace than real clinical systems ### Known Dependencies - React 18.3.1, TypeScript, Vite - Tailwind CSS for utility classes - Framer Motion 11.15.0 for animations - Lucide React 0.468.0 for icons - fuse.js will need to be installed for Task 12 ### Sidebar Label Convention (IMPORTANT) - Sidebar uses CV-friendly labels, NOT clinical jargon - Summary (same), Experience (not Consultations), Skills (not Medications), Achievements (not Problems), Projects (not Investigations), Education (not Documents), Contact (not Referrals) - The clinical metaphor is in the VIEW LAYOUT, not the navigation labels - Each view should look like its clinical equivalent but the nav label tells the user what CV section they're looking at ### Visual Review (Claude in Chrome) - Dev server runs on `http://localhost:5173` throughout the loop - Use browser tools (`tabs_context_mcp`, `navigate`, `computer` screenshot) to verify visual output - App has boot→ECG→login→PMR sequence (~15s on first load). Wait before screenshotting. - Once in PMR phase, navigate views via hash routes: `#summary`, `#experience`, `#skills`, `#achievements`, `#projects`, `#education`, `#contact` - If browser tools fail, skip visual review and note in iteration log — don't block progress ### Critical Styling Notes - Design direction is **Clinical Luxury** — clinical structure, premium execution - Premium UI font loaded from Fonts/ directory (Elvaro Grotesque or Blumir, NOT Inter/Roboto) - Geist Mono for coded entries and timestamps (NOT Fira Code) - Multi-layered shadows on cards — NOT flat/borderless - Clinical alert uses spring animation (Framer Motion type: "spring"), not ease-out - View switching INSTANT — no crossfade, no slide between views - Login typing: 80ms/char username, 60ms/dot password. Button is USER-INTERACTIVE (not auto-triggered) - Consultation expand/collapse: height animation ONLY, no opacity fade on content ## Iteration Log ### Iteration 1 — Task 1: Design system foundation and font setup **Completed:** Task 1 **Changes made:** - Added Geist Mono font to Google Fonts import in index.html (replacing reliance on Fira Code for PMR components) - Extended Tailwind config PMR color tokens: added card, text-primary, text-secondary, text-on-dark variants, border colors, selected-row, alert colors - Fixed borderRadius.card from 16px to 4px (clinical system requirement) - Added borderRadius.login: 12px (exception for login card per spec) - Added boxShadow.pmr: minimal clinical shadow - Added PMR-specific CSS custom properties in index.css (--pmr-* variables) - Added utility classes: .pmr-theme, .font-inter, .font-geist-mono **Codebase patterns discovered:** - The project uses both legacy design tokens (for boot/ECG phases) AND new PMR tokens (for clinical interface) — both need to coexist - Geist Mono is the correct font for coded entries, timestamps, and clinical codes in PMR (NOT Fira Code) - Border radius convention: 4px default for clinical components, 12px for login card only, 16px for legacy components - CSS custom properties namespaced with --pmr- prefix for clarity **Quality checks:** All passed (typecheck, lint, build) **Visual review:** N/A (configuration task, no visual component) **Issues encountered:** None **Design decisions:** - Kept legacy tokens in place to avoid breaking boot/ECG components - Used --pmr- namespace for all PMR tokens to distinguish from legacy design system - Extended Tailwind colors rather than replacing them — allows both themes to work simultaneously ### IMPORTANT — Design Guidance is Pre-Baked Do NOT invoke the `/frontend-design` skill at runtime — it was pre-run and the output is embedded in each ref file under "Design Guidance (from /frontend-design)". Previous iterations STALLED because the skill output consumed the entire context window. The guidance is now in the ref files — just read and implement. ### ECG Reference Implementation `ECGCombined.tsx` in the project root is a Remotion version of the ECG animation with a superior mask-based text reveal technique. Task 1b references this for the canvas implementation. ### Iteration 2 — Task 1b: Rebuild boot sequence and ECG animation **Completed:** Task 1b **Changes made:** - **BootSequence.tsx**: Completely refactored from hardcoded HTML strings to config-driven architecture - Created type-safe `BootConfig`, `BootLine`, `BootLineType` interfaces - Individual line components: `BootLineHeader`, `BootLineStatus`, `BootLineSeparator`, `BootLineField`, `BootLineModule`, `BootLineReady` - Added CRT scanlines overlay during boot phase - Cursor now captures its screen position via ref and passes to parent via `onCursorPositionReady` callback - Cursor morph animation: block cursor scales down to 0 width over 300ms before ECG starts - Reduced motion support: instant boot completion, skips to ECG immediately - **ECGAnimation.tsx**: Rebuilt with mask-based text reveal technique from ECGCombined.tsx - Added `startPosition` prop to receive cursor position from BootSequence - ECG trace now starts from cursor position (with `startOffsetX`) instead of x=0 - Implemented offscreen canvas pre-rendering for text stroke - Mask-based text reveal: clipping region follows trace head, revealing pre-rendered text - Added connector lines between letters at baseline using `CONNECTOR_PROFILES` - Letter profiles define connector insets for natural-looking baseline connections - Multi-layer neon glow: outer (6px, 25% opacity), inner (2px solid) - Flatline draw phase extends to right edge after text completion - Background transitions from black to `#1E293B` (login background) - Reduced motion support: instant transition to PMR phase - **App.tsx**: Updated to pass cursor position between BootSequence and ECGAnimation - Added `cursorPosition` state - `handleCursorPositionReady` captures position from BootSequence - Passed to ECGAnimation as `startPosition` prop **Codebase patterns discovered:** - Canvas animation performance: pre-render text to offscreen canvas, then drawImage through clip region - Cursor-to-dot transition requires DOM ref position capture, not just CSS animation - World-space coordinates (headWX) vs screen-space coordinates (headSX) separation is critical - Viewport scrolling logic: offset calculated as `headWX - headSX` keeps trace visible - Connector profiles per character (C, O, D, L, E have special insets) make letter connections look natural - Background color transition handled via CSS transition on container, not canvas fill **Quality checks:** All passed (typecheck, lint, build) - TypeScript: No errors - ESLint: 1 pre-existing warning in AccessibilityContext.tsx (not our changes) - Build: Successful, 388KB bundle **Visual review:** N/A (animation component — visual verification would require browser screenshot) **Issues encountered:** None **Design decisions:** - Kept Fira Code for terminal/boot phase (it's the authentic clinical terminal aesthetic) - Used ECGCombined.tsx's mask technique but adapted for canvas API (not SVG like the Remotion version) - Beat amplitudes: 0.3 → 0.55 → 0.85 → 1.0 (same as original implementation) - Letter spacing: LETTER_W 72px, LETTER_G 10px, SPACE_W 30px (matches original, tighter than ECGCombined) - Morph animation uses Framer Motion scaleX/width/opacity for smooth cursor-to-dot transition **Next task:** Task 2 — Set up premium font ## Manual Intervention — 2026-02-12 ### Reason: Design direction changed from "Clinical Utilitarian" to "Clinical Luxury" ### Changes made: - Rewrote IMPLEMENTATION_PLAN.md — leaner format, tasks point to ref files for detail - Rewrote guardrails.md — updated shadow rules, font rules, login pacing, luxury direction - Updated all Ralph/refs/*.md files to align with Clinical Luxury direction - Updated CLAUDE.md with new login typing spec (80ms/char, user-interactive button) - Updated ref-design-system.md login typing speed ### Tasks reset: Task 2 (LoginScreen — needs new typing speed + interactive button + premium font) ### Tasks added: New Task 2 (font setup) inserted before LoginScreen rebuild (now Task 3) ### Context for next iteration: - The design direction is "Clinical Luxury" — clinical STRUCTURE, premium EXECUTION - All ref files now say "Clinical Luxury" not "Clinical Utilitarian" or "faithful reproduction" - Cards get multi-layered shadows (not flat/borderless) - Premium font from Fonts/ directory replaces Inter (see CLAUDE.md Typography section) - Login screen typing is slower (80ms/char, 60ms/dot) and the button is USER-CLICKED - Sidebar labels are CV-friendly (Experience, Skills, etc.) — clinical metaphor is in the LAYOUT ### New guardrails added: - Shadow guardrail updated: multi-layered shadows required (was: "no shadows") - Font guardrail added: use [UI font] from Fonts/, not Inter/Roboto - Login guardrail added: 80ms/char typing, user-interactive button