-
CLINICAL TERMINAL v3.2.1
+
setPhase('ecg')} />
+ )}
+
+ {phase === 'ecg' && (
+
)}
diff --git a/src/components/BootSequence.tsx b/src/components/BootSequence.tsx
new file mode 100644
index 0000000..e415384
--- /dev/null
+++ b/src/components/BootSequence.tsx
@@ -0,0 +1,95 @@
+import { motion, AnimatePresence } from 'framer-motion'
+import { useEffect, useState } from 'react'
+
+interface BootLine {
+ html: string
+ delay: number
+}
+
+const bootLines: BootLine[] = [
+ { html: 'CLINICAL TERMINAL v3.2.1', delay: 0 },
+ { html: 'Initialising pharmacist profile...', delay: 220 },
+ { html: '---', delay: 220 },
+ { html: 'SYSTEM NHS Norfolk & Waveney ICB', delay: 220 },
+ { html: 'USER Andy Charlwood', delay: 220 },
+ { html: 'ROLE Deputy Head of Population Health & Data Analysis', delay: 220 },
+ { html: 'LOCATION Norwich, UK', delay: 220 },
+ { html: '---', delay: 220 },
+ { html: 'Loading modules...', delay: 220 },
+ { html: '[OK] pharmacist_core.sys', delay: 220 },
+ { html: '[OK] population_health.mod', delay: 220 },
+ { html: '[OK] data_analytics.eng', delay: 220 },
+ { html: '---', delay: 220 },
+ { html: '> READY — Rendering CV...', delay: 220 },
+]
+
+interface BootSequenceProps {
+ onComplete: () => void
+}
+
+export function BootSequence({ onComplete }: BootSequenceProps) {
+ const [isVisible, setIsVisible] = useState(true)
+ const [lineDelays, setLineDelays] = useState([])
+
+ useEffect(() => {
+ const delays: number[] = []
+ let totalDelay = 0
+ bootLines.forEach((line) => {
+ delays.push(totalDelay)
+ totalDelay += line.delay
+ })
+ setLineDelays(delays)
+
+ const totalBootTime = totalDelay
+ const fadeStartTime = totalBootTime + 400
+
+ const fadeTimer = setTimeout(() => {
+ setIsVisible(false)
+ }, fadeStartTime)
+
+ const completeTimer = setTimeout(() => {
+ onComplete()
+ }, fadeStartTime + 800)
+
+ return () => {
+ clearTimeout(fadeTimer)
+ clearTimeout(completeTimer)
+ }
+ }, [onComplete])
+
+ return (
+
+ {isVisible && (
+
+
+ {bootLines.map((line, index) => (
+
+ ))}
+
+
+
+ )}
+
+ )
+}