114 lines
7.0 KiB
Plaintext
114 lines
7.0 KiB
Plaintext
# Progress Log — React Conversion Phase
|
||
|
||
## Codebase Patterns
|
||
- **Source of truth**: `References/concept.html` contains the complete working HTML implementation. All animations, timing, colors, and styling must be preserved exactly when porting to React.
|
||
- **Tech stack**: React 18+, TypeScript, Vite, Tailwind CSS, Framer Motion, Lucide React
|
||
- **Project structure**: Components in `src/components/`, hooks in `src/hooks/`, types in `src/types/`, utilities in `src/lib/`
|
||
- **Animation approach**: Framer Motion for complex sequences (boot, ECG), CSS transitions for simple hover effects, IntersectionObserver (via hook) for scroll-triggered animations
|
||
- **SVG animations**: Use Framer Motion's `pathLength` prop for drawing effects, or CSS `stroke-dasharray`/`stroke-dashoffset` for skill gauges
|
||
- **Skill gauge math**: `circumference = 2 * Math.PI * radius`, `strokeDashoffset = circumference * (1 - level / 100)`, rotate -90deg to start from top
|
||
- **Boot sequence timing**: 14 lines × 220ms = ~3080ms, plus 400ms pause, 800ms fade = ~4.28s total
|
||
- **ECG timing**: Flatline 1000ms + 3 beats × 600ms + holds 300ms + branching 1500ms + fade 500ms = ~5.5s
|
||
- **Color palette**:
|
||
- ECG phase: #000 (black), #00ff41 (green), #00e5ff (cyan), #3a6b45 (dim green)
|
||
- Final design: #00897B (teal), #FF6B6B (coral), #0F172A (heading), #334155 (text), #94A3B8 (muted)
|
||
- **Fonts**: Fira Code (boot), Plus Jakarta Sans (primary), Inter Tight (secondary)
|
||
- **Responsive breakpoints**: 768px (tablet), 480px (mobile)
|
||
|
||
## Iteration Log
|
||
|
||
### Phase Transition — React Conversion Setup
|
||
- Previous phase completed: Single HTML file `concept.html` fully built with all 9 tasks
|
||
- New phase started: Convert HTML concept to React + TypeScript + Vite project
|
||
- IMPLEMENTATION_PLAN.md updated with 12 React-specific tasks
|
||
- RALPH_PROMPT.md updated with explicit /frontend-design skill requirement for all visual components
|
||
- This progress.txt reset for new phase
|
||
|
||
### Iteration 4 — Task 5: Build FloatingNav component
|
||
- **Completed**: Task 5 - Build FloatingNav component
|
||
- **Files created**:
|
||
- `src/hooks/useActiveSection.ts` - IntersectionObserver hook for tracking active nav section
|
||
- `src/components/FloatingNav.tsx` - Floating pill navigation with active tracking
|
||
- **Files modified**:
|
||
- `src/index.css` - Added scrollbar-hide utility and smooth scroll behavior
|
||
- `src/App.tsx` - Integrated FloatingNav and added section IDs for scroll targets
|
||
- **Design decisions**:
|
||
- Used IntersectionObserver with rootMargin '-20% 0px -70% 0px' for accurate section detection
|
||
- Framer Motion layoutId for smooth indicator dot animation between nav items
|
||
- Active section is the topmost visible section (sorted by DOM order)
|
||
- Navigation uses button elements for accessibility and proper click handling
|
||
- Smooth scroll behavior via CSS `scroll-behavior: smooth` on html element
|
||
- Responsive: horizontal scroll with hidden scrollbar on mobile
|
||
- **Quality checks**: `npm run typecheck` ✓, `npm run lint` ✓, `npm run build` ✓
|
||
- **Learnings**:
|
||
- IntersectionObserver thresholds array allows precise tracking of section visibility
|
||
- Using a ref to track visible sections prevents React re-render race conditions
|
||
|
||
<!-- Iterations will be logged here as tasks are completed -->
|
||
|
||
### Iteration 3 — Task 4: Build ECGAnimation component
|
||
- **Completed**: Task 4 - Build ECGAnimation component
|
||
- **Files created**:
|
||
- `src/components/ECGAnimation.tsx` - Canvas-based ECG animation with heartbeat waveforms and name drawing
|
||
- **Files modified**:
|
||
- `src/App.tsx` - Updated to use ECGAnimation component instead of placeholder
|
||
- **Design decisions**:
|
||
- Used canvas API with requestAnimationFrame for smooth 60fps animation
|
||
- Ported exact ECG waveform generation from concept.html (PQRST pattern)
|
||
- Ported letter waveform interpolation for "ANDREW CHARLWOOD" name drawing
|
||
- Implemented glow effects using canvas shadowBlur
|
||
- Added scanline overlay (4px horizontal lines) for retro effect
|
||
- Added radial gradient vignette for atmosphere
|
||
- Background transitions from black to white during exit phase
|
||
- Used Framer Motion AnimatePresence for component-level exit animation
|
||
- **Animation timing preserved**:
|
||
- 4 heartbeat complexes with amplitudes: 0.3, 0.55, 0.85, 1.0
|
||
- Trace speed: 450px/s (scaled responsively)
|
||
- Hold time after text: 0.75s
|
||
- Exit fade: 0.8s
|
||
- Total duration: ~5-6 seconds
|
||
- **Quality checks**: `npm run typecheck` ✓, `npm run lint` ✓, `npm run build` ✓
|
||
- **Learnings**:
|
||
- Canvas-based animations need careful cleanup on unmount (cancelAnimationFrame)
|
||
- Device pixel ratio (dpr) handling required for crisp rendering on high-DPI displays
|
||
- Responsive scaling: `Math.min(1.2, Math.max(0.35, vw / 1400))`
|
||
|
||
### Iteration 1 — Task 1: Initialize React project
|
||
- **Completed**: Task 1 - Initialize React project with Vite + TypeScript + Tailwind
|
||
- **Files created**:
|
||
- `package.json` with dependencies: React 18, Framer Motion, Lucide React, Tailwind
|
||
- `tsconfig.json`, `tsconfig.app.json`, `tsconfig.node.json` for TypeScript
|
||
- `vite.config.ts` with path alias `@/` -> `./src/`
|
||
- `tailwind.config.js` with custom colors (teal, coral, ecg-green), fonts, shadows
|
||
- `postcss.config.js` for Tailwind processing
|
||
- `index.html` with Google Fonts (Fira Code, Plus Jakarta Sans, Inter Tight)
|
||
- `src/index.css` with Tailwind directives and CSS custom properties
|
||
- `src/main.tsx` entry point
|
||
- `src/App.tsx` placeholder component
|
||
- `src/types/index.ts` with TypeScript interfaces
|
||
- `src/lib/utils.ts` with skill gauge calculation helper
|
||
- `eslint.config.js` with React hooks and refresh rules
|
||
- **Project structure created**: `src/components/`, `src/hooks/`, `src/lib/`, `src/types/`
|
||
- **Quality checks**: `npm run typecheck` ✓, `npm run build` ✓, `npm run lint` ✓
|
||
- **Learnings**:
|
||
- Need `src/vite-env.d.ts` with `/// <reference types="vite/client" />` for CSS imports
|
||
- Vite refuses to scaffold in non-empty directory, so manual setup was needed
|
||
|
||
### Iteration 2 — Task 2 & 3: Project structure and BootSequence
|
||
- **Completed**: Task 2 (Set up project structure and types) - was already done in Task 1
|
||
- **Completed**: Task 3 - Build BootSequence component
|
||
- **Files created**:
|
||
- `src/components/BootSequence.tsx` - Terminal typing animation using Framer Motion
|
||
- **Design decisions**:
|
||
- Used Framer Motion's `motion.div` with `initial`/`animate` props for line reveals
|
||
- Each line animates with opacity 0→1, translateY 8px→0 over 400ms
|
||
- Staggered delays calculated from cumulative 220ms per line
|
||
- Blinking cursor implemented with CSS animation class `animate-blink`
|
||
- Used `AnimatePresence` for smooth exit fade (800ms)
|
||
- **Boot sequence timing preserved**: 14 lines × 220ms + 400ms pause + 800ms fade = ~4.28s
|
||
- **Quality checks**: `npm run typecheck` ✓, `npm run build` ✓, `npm run lint` ✓
|
||
- **Learnings**:
|
||
- Framer Motion's delay prop uses seconds, not milliseconds
|
||
- Used `dangerouslySetInnerHTML` for colored spans within boot lines (matches concept.html structure)
|
||
- CSS classes for blink/seed-pulse animations already existed in index.css from Task 1
|