6.8 KiB
6.8 KiB
Guardrails — React Conversion
Standard Guardrails
Frontend-design skill requirement
- When: Writing ANY component with visual styling, animations, or UI elements
- Rule: You MUST invoke the
/frontend-designskill before writing code. This applies to: BootSequence, ECGAnimation, FloatingNav, Hero, Skills, Experience, Education, Projects, Contact, Footer, and any styled component. - Why: The frontend-design skill provides specialized capabilities for creating polished, professional-grade visual output. Skipping it results in lower quality design.
Boot sequence consistency
- When: Implementing BootSequence component
- Rule: Boot text must match concept.html exactly: "CLINICAL TERMINAL v3.2.1", "Initialising pharmacist profile...", SYSTEM/USER/ROLE/LOCATION labels with values, loading modules line, three [OK] lines, "---", and final ready line. Use Fira Code font, green #00ff41 for [OK] and values, cyan #00e5ff for labels, dim green #3a6b45 for other text.
- Why: Boot sequence is the shared identity across all concepts. Must be identical.
ECG animation fidelity
- When: Implementing ECGAnimation component
- Rule: Timing and visual effects must match concept.html exactly: flatline 1000ms, three heartbeats with amplitudes 40px→60px→100px, color shift #00ff41→#00C9A7→#00897B, branching lines from third R peak, background transition black→white.
- Why: The ECG animation is the signature visual effect. Any deviation breaks the experience.
CV content accuracy
- When: Adding CV content to components
- Rule: Use the expanded CV_v4.md content. Key roles in order: Interim Head (May-Nov 2025), Deputy Head (Jul 2024-Present), High-Cost Drugs & Interface Pharmacist (May 2022-Jul 2024), Pharmacy Manager Tesco (Nov 2017-May 2022), Duty Pharmacy Manager Tesco (Aug 2016-Nov 2017). Include Mary Seacole Programme in education. Include key achievements with specific numbers (£14.6M, 14,000 patients, £2.6M, 70%, 200hrs, £1M).
- Why: The CV data must be accurate and complete. Missing roles or wrong dates would be a critical error.
TypeScript strictness
- When: Writing any TypeScript code
- Rule: No
anytypes. Define interfaces for all data structures. Use proper React.FC types or function component signatures with typed props. Enable strict mode in tsconfig.json. - Why: Type safety is a core benefit of the React conversion.
anydefeats the purpose.
Google Fonts loading
- When: Setting up index.html
- Rule: Use preconnect links to fonts.googleapis.com AND fonts.gstatic.com (with crossorigin), then the font CSS link. Load ALL fonts: Fira Code, Plus Jakarta Sans, Inter Tight. Test that fonts actually render.
- Why: Fonts are critical to the design identity. Missing fonts break the visual concept.
Transition timing
- When: Building the boot-to-design transition
- Rule: Boot phase should take ~4 seconds. ECG animation should take ~5-6 seconds. Total time from page load to fully revealed design: no more than 10 seconds.
- Why: Too long and users will leave. Too short and the effect is lost.
No console errors
- When: Writing JavaScript/TypeScript
- Rule: No errors in the browser console. Handle edge cases: elements that might not exist, animation cleanup on unmount, proper dependency arrays in hooks.
- Why: Console errors suggest broken functionality and are a quality check failure.
Responsive breakpoints
- When: Adding responsive CSS/Tailwind classes
- Rule: Must work at 3 breakpoints: desktop (>768px), tablet (<=768px), mobile (<=480px). Navigation must be usable at all sizes. Content must not overflow horizontally. Touch targets must be reasonable size.
- Why: CVs are often viewed on mobile devices.
Scroll animation observer
- When: Implementing scroll-triggered animations
- Rule: Use IntersectionObserver via custom hook (useScrollReveal), NOT scroll event listeners. Set appropriate threshold (0.1-0.15). Animations should only play once (don't re-trigger on scroll up).
- Why: IntersectionObserver is more performant and reliable than scroll listeners.
Tailwind CSS usage
- When: Writing component styles
- Rule: Use Tailwind utility classes for all styling. Only use inline styles or CSS modules for dynamic values that can't be expressed with Tailwind (e.g., stroke-dashoffset calculations). Extend Tailwind config for custom colors.
- Why: Consistent styling approach, smaller bundle size, better maintainability.
Project-Specific Guardrails
Framer Motion for complex animations
- When: Animating the boot sequence, ECG paths, branching lines
- Rule: Use Framer Motion's
motioncomponents and props (initial, animate, transition). UsepathLengthfor SVG drawing animations. UseAnimatePresencefor exit animations. Define transition objects with exact timing from concept.html. - Why: Framer Motion provides declarative, performant animations that are easier to maintain than imperative JS.
Skill circle calculation
- When: Building SVG circular progress gauges in Skills component
- Rule: The circumference formula is
2 * Math.PI * radius.strokeDasharray = circumference.strokeDashoffset = circumference * (1 - level / 100). The circle MUST havetransform: rotate(-90deg)to start progress from 12 o'clock position. - Why: Wrong math or missing rotation produces circles that fill from the wrong position or have incorrect percentages.
Component file structure
- When: Creating new components
- Rule: One component per file in
src/components/. Named exports for components. Props interface defined at top of file. Follow naming: PascalCase for components (BootSequence.tsx), camelCase for hooks (useScrollReveal.ts). - Why: Consistent organization makes the codebase maintainable.
Lucide React icons
- When: Adding icons to Contact or other sections
- Rule: Use Lucide React icons instead of unicode symbols. Import specific icons:
import { Phone, Mail, Linkedin, MapPin } from 'lucide-react'. Size icons consistently (default 24px or specified size prop). - Why: Lucide provides consistent, scalable SVG icons that match the design system.
Custom hooks for reusable logic
- When: Implementing scroll reveal, active section tracking
- Rule: Extract reusable logic into custom hooks in
src/hooks/. Hooks should be composable and return values/functions needed by components. Name withuseprefix. - Why: Keeps components clean, enables reuse, follows React best practices.
Vite configuration
- When: Setting up the project build
- Rule: Use Vite's default React template. Configure path aliases in
vite.config.tsfor clean imports (e.g.,@/components/Hero). Ensurebuild.outDiris set correctly. - Why: Vite provides fast dev server and optimized production builds.