"use client" import { useEffect, useRef, useState } from 'react' const BOOT_LINES = [ 'QUINTA-BIOS (C) 2026, Pietro Quintavalle Systems', 'CPU: AMD Ryzen 7 9800X3D @ 5.00GHz .................... OK', 'Memory Test: 32768MB ................................... OK', 'Detecting storage: Proxmox VE / UNRAID / TrueNAS ....... OK', '', 'Booting from /dev/homelab ...', '', '[ OK ] Started Proxmox VE 8 hypervisor', '[ OK ] Mounted UNRAID 7.3.1 parity array', '[ OK ] Mounted TrueNAS ZFS RAID 10', '[ OK ] Started Docker daemon (LXC + KVM)', '[ OK ] Established Cloudflare Tunnel ....... 0 open ports', '[ OK ] Started Pangolin + Traefik reverse proxy', '[ OK ] Started Fail2Ban / Crowdsec / Authelia', '[ OK ] Loaded Grafana + Prometheus', '[ OK ] Mounted /home/quinta', '[ OK ] Uptime check ........................ 90%+', '[ OK ] Loading personal_website.tsx', ] const GREETING_LINES = [ 'Welcome back, root.', "Hi, I'm Pietro — systems engineer, developer, homelabber.", ] const DURIN_ART = ` ______________ _ _,-----------._ ___ | | (_,.- _,-'_,-----------._\`-._ _)_) | THE _ _ _ | | ,'_,-' ___________ \`-._\`. | | / \\|_)| \\ | \`' ,',' _,-'___________\`-._ \`.\`. | |__\\_/| \\|_/ | ,',' ,'_,-' . \`-._\`. \`.\`. | | /,' ,',' >|< \`.\`. \`.\\ | OF THE _ _ | // ,',' >< ,^. >< \`.\`. \\\\ | |_)||\\|/_(_ | // /,' >< / | \\ >< \`.\\ \\\\ | | \\|| |\\_|_) | // // >< \\/\\^/\\/ >< \\\\ \\\\ |______________| ;; ;; \`---' :: :: || || (____ || || DOORS OF DURIN _||__||_ ,'----. _||__||_ (o.____.o)____ \`---' ____(o.____.o) | | /,--.) (,--.\\ | | | |(( -\`___ ___\` ))| | | | \\\\,'', \`. .' .\`\`.// | | | | // (___,'. .'.___) \\\\ | | /| | ;;)) ____) . . (____ ((\\\\ | |\\ \\|.__ | ||/ .'.--.\\/ \`/,--.\`. \\;: | __,|; |\`-,\`;.| :/ /,' \`)-' \`-(' \`.\\ \\: |.;',-'| | \`.. ' / \\__.' \`.__/ \\ \` ,.' | | |,\\ /, ,\\ /,| | | ||: : ) . ( : :|| | /| |:; |/ . ./|\\, , \\| :;| |\\ \\|.__ |/ : ,/- <--:--> ,\\. ; \\| __,|; |\`-.\`\`: \`'/-. '\\|/\` ,-\\\`; ;'',-'| | \`.. ,' \`' ' \` \`. ,.' | | || : : || | | || | | || | | || | | || | | |' | _ | \`| | | | | '|)) | | | ;____: \`._ \`' _,' ;____: {______} \\___________________/ {______} SSt |______|_______________________________|______|` const BALROG_ART = `############################+##++++++########+++++-----. ------------ . - --.--- --.--.------...---------------..--- ###############################+++++++####+++++----- --- - ---- -- -. ..- - - ------------------------------- ##########################+++++++++++++#####+++---. . -- - - - - .--.----------------------------- ########################+++#+++++++++######++++-. ..--++++++------..----- - ------------.- --------- ###########################+##+++++++++++##++- -++++++++--+--------.- .. ...-.. - ----------------.--------- ############################+++++++++++++#++-+ - -++++++++++++------+++---++------------------------- -------------.--- #############################++++++++++++#++++- --- ++++++++++++++++--+++++++------------------------------- -------------.--- #############################++++++++++++++++--- .+##+++++++++++++++++++++++++---------------------------.---------------- ############++#+###+#+++#####++++++++++++++-- --- -- -+###+++++++++++++++++++++++++----+--------------------------------------- ###########++++++++++++#++++++++++++++--..---- . .-- .. -+#####++++++++++++++++++++++++-+--++++------------------------------------- ############+++++++++++++++++++++++++++++++++.+ ..--.- +#########+++++++++++++++++++++++++++----+------------------------.----------- ############++++++++++++++++++++++-+++++++++++++.. + .++#####++#++++#++++++++++++++++++++++++++-------+--------------------- --------- ########+#+++++++++++++++++++++---++++-+++++++++.. -+#########-+ .+++++++++++++++++++++++-++++-+++++----+-------------------+-------- +######+#+++++++++++++++++++++-+++++++-++++++++++##+-.+++++++#+ +++++++++++++++++++++++-----+++++++++++-----+--------+------------- ++##+++++++++++++++++++++++++++++++++++++-+++.++++-+ .+++++-++++++++++++++++++++++----+---------------+++++++-----+---------------- ++++++++++++++++++++++++++##+++++++++++++++. ++# ++ +-.++++++++++++++++#++++---+------------------------+-+++---+++-+---+-----.---- +++++++++++++++++++++++###++++++++++++++++++-+++- +++ ++++++++++++++#++++-++----+-+----------------------+---++++++++----+--++++---- +++++++++++++++++++++###++++++++++++++++++++++++ +#+#+#+#+++#######+++#----------------------------------+-++----++-+++--+++++++----. +++++++++++++++++++++++#++++++++++++-++++++++++##++++#++#+++#+++#+#+++++++++--+----------+------------------+-++--++-+--++++++-++-.--- ++++++++++++++++++++++++++++++++++++++++++#+++++-++++##+#++##++####+++++++++++-+-----------+------------------+---++++++++++++++-++--- +++++++++++++++++++++++++++++++++++++++--++++++#++++###+#++#+#++++++++++++++++++++---+---------------------------+++++++++++++++++++-- +++++++++++++++++++++++++++++-------++--+++++#++++#+#######+#++++#+#-++-+++++++++++------------------------------+--++++++++++++++++-- +++++++++++++++++++++++++++-------+-----+#+++#+++# #.# #+####+###++--+++++++++++++--------------.-------------+-++--++++++++++++++-- +++++++++++++++++++++-----------------+++#+--# . - - .+####+##++-----++++++++--+----+-+--------.--------------+-----+++++++++++++-- +++++++++++++++++++++-------++----------#++++# - #. ####+-+-.+--+++++++---+++++++----------------------------.--++++++++++++-- +++++++++++++--+++++-+-------+----------+++##. . + +#+- -++---+ ++++----+++++++++---------------------------..+++++++++++++-- +++++++++++++-++++++---------------------#++ ---. +#- +++-. -++----++-+-+-+++++--------------------------..-+++++++++++++-- ++++++++++++++-----+--------------++++++++#+ +...-- + . - ----+-+++--++-+++-----------------------.---++++++++++++++-- ++++++++----++--+++----------+++++++++++-++#++. . . ----+----++---+--++-------------------------+ +++++++++++++--- +++++++++---+--------------++++++++++++++++...-. . -----------+---++++------------------------++++++++++++++++--- +++++++---+-++-+++-+-----+++++++++++++++++------ .. ---------+-----+++++-+-----------------++++++++++++++++++---- +++++++-+++-+----++------+++++++++++++++++++++--- ....----+--+------++++-++------------.+.+++++++++++##+++++++---- ++++++++++++++++------+++++++++++++++++++++++++--. . ... ++---+--+----++++---++-------.+-.+++++++++++++#######+------ ++++---++++------+---++++++++++++++++++++++++++---. ...-.--+--+---++--+------+-+--.-.++.+#+++#+++++###++++++#--------- -++++.--+++++---+----+++++++++++++++++++++++++++-+-... ......---+++-++----++-----+--.---++####+++++###--++####++-----.---- ++++-----+----------++++++++++++++++++++++++++++++--.... ..------++++--------------.+- ############+++##+###+--------------- +++-+++------------++++++++++++++++++++++++++++++----..... ..----+. -+---------- ---..+###+####+###-#####++-+--.--------------- +++++++++--.------+++++++++++++++++++++++++++++. -----.... . . ..-++-+--+----------- .#++++#++##+--++++---+-----------.----------- -----+-+++--------++++++++++++++++++++++++++++++---.--.... . .. ---++-.+------------ .+-++##--#+--++--.----------------------------- -------+++--------++++#++++++++++++++++++++++-+-------..-. .---+--+++---------. +#-#+#+--+------.---.---.----- ----------------.. -------++++++-+------.+++++++++++++++-++++++++-- ----..... ..----+--+.++-------- +--#++-------------------------....-.---------..-- ------++++++++++++---+--##++++++++++++++++++++---------......-.--+++-.-++---.---. -##++----------------------- ---.....---------...... -++---++++++#+++++##++...+#++++++++ +++++++++---------...-.---.++++...--.-+-----..+#+-----------.---------------.... ......-......... -------+++-+++#+# ++#+....+##+#++++#+++++++++----++++---...----++++-..+.--++---.+#+-------------------------..... . ....... . ... ++----+++++++-+---###+-+..-##+##+##+++++++++-.--------.--------+-+--------++---.#-----------..----------...... .. . .. ++++-+++++++++++++++##++-..##++++##+++++++++-+----..----+---+--++---------++-------------------------...-. . . .... ++++++++++++++++++++++##-..+++++++ ++++++ +- - --------------+-.---------------- ----------.----------.... . . -+++++++-+++++++++++++#+--++.++-----------------------. .--- --------------------------------------...--..... ...... . -++++--++++++++++++++++-++ -++.-------.------------ ------.---------.....--------------------- .--- ....... ...... ----------++++--------+++.----------..--------.------------ ...-.-.-.----------------------..---.--. .. ........ -----.-...-------------------------------.------ -----..----...-.........-----------------.. .-.... ....... ... . ........ .--------------------------------------- --... ---......----.. . - ----------.--...-... ......... .. ... ..---------------.--.-------------...-.---------.. ....-...... --- --- ---.-----...... . ...... .-----.-.----------.---------------..--------.--...... . ..----------------.-.. .. . ...--------------------------...----.--------.-..---.-. .---------------------. . ` const DOOM_ART = `######## ###### ###### ## ## ## ## ## ## ## ## #### #### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######## ###### ###### ## ##` type Phase = 'boot' | 'greet' | 'prompt' | 'exit' type EggView = 'none' | 'moria' | 'balrog' | 'iddqd' | 'idkfa' const EGG_ART: Record, string> = { moria: DURIN_ART, balrog: BALROG_ART, iddqd: DOOM_ART, idkfa: DOOM_ART, } const EGG_CAPTIONS: Record, string> = { moria: 'the doors of durin, lord of moria — speak, friend, and enter', balrog: 'a demon of the ancient world — YOU SHALL NOT PASS', iddqd: 'IDDQD — GOD MODE ON — degreelessness achieved', idkfa: 'IDKFA — armed to the teeth — all keys, all ammo', } const EGG_DURATION = 4200 const IDLE_TIMEOUT = 15000 export default function BootSequence({ onComplete, onReboot }: { onComplete: () => void; onReboot: () => void }) { const [visibleBoot, setVisibleBoot] = useState(0) const [visibleGreet, setVisibleGreet] = useState(0) const [phase, setPhase] = useState('boot') const [cmd, setCmd] = useState('') const [eggView, setEggView] = useState('none') const [eggBusy, setEggBusy] = useState(false) const doneRef = useRef(false) const phaseRef = useRef('boot') const eggViewRef = useRef('none') const timers = useRef[]>([]) const idleTimer = useRef | null>(null) const overlayRef = useRef(null) const inputRef = useRef(null) useEffect(() => { phaseRef.current = phase }, [phase]) useEffect(() => { eggViewRef.current = eggView }, [eggView]) const finish = () => { if (doneRef.current) return doneRef.current = true timers.current.forEach(clearTimeout) timers.current = [] if (idleTimer.current) clearTimeout(idleTimer.current) setPhase('exit') const t = setTimeout(onComplete, 380) timers.current.push(t) } const fastForward = () => { if (phaseRef.current === 'boot') setVisibleBoot(BOOT_LINES.length) else if (phaseRef.current === 'greet') setVisibleGreet(GREETING_LINES.length) } const resetIdleTimer = () => { if (idleTimer.current) clearTimeout(idleTimer.current) idleTimer.current = setTimeout(() => { if (phaseRef.current === 'prompt' && eggViewRef.current === 'none') finish() }, IDLE_TIMEOUT) } const triggerEgg = (view: Exclude) => { if (eggBusy) return setEggBusy(true) setEggView(view) const t = setTimeout(() => { setEggView('none') setCmd('') setEggBusy(false) resetIdleTimer() inputRef.current?.focus() }, EGG_DURATION) timers.current.push(t) } useEffect(() => { document.body.style.overflow = 'hidden' const reduced = typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches if (reduced) { setVisibleBoot(BOOT_LINES.length) setVisibleGreet(GREETING_LINES.length) setPhase('prompt') return () => { document.body.style.overflow = '' } } let i = 0 const stepBoot = () => { i += 1 setVisibleBoot(i) if (i < BOOT_LINES.length) { const line = BOOT_LINES[i] const delay = line === '' ? 90 : 60 + Math.random() * 90 timers.current.push(setTimeout(stepBoot, delay)) } else { timers.current.push(setTimeout(() => setPhase('greet'), 450)) } } timers.current.push(setTimeout(stepBoot, 240)) overlayRef.current?.focus() return () => { document.body.style.overflow = '' timers.current.forEach(clearTimeout) timers.current = [] } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) useEffect(() => { if (phase !== 'greet') return let i = 0 const stepGreet = () => { i += 1 setVisibleGreet(i) if (i < GREETING_LINES.length) { timers.current.push(setTimeout(stepGreet, 950)) } else { timers.current.push(setTimeout(() => setPhase('prompt'), 1900)) } } timers.current.push(setTimeout(stepGreet, 300)) // eslint-disable-next-line react-hooks/exhaustive-deps }, [phase]) useEffect(() => { if (phase !== 'prompt') return inputRef.current?.focus() resetIdleTimer() return () => { if (idleTimer.current) clearTimeout(idleTimer.current) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [phase]) const handleOverlayClick = () => fastForward() const handleOverlayKeyDown = () => fastForward() const handleInputKeyDown = (e: React.KeyboardEvent) => { if (e.key !== 'Enter' || eggBusy) return const value = cmd.trim().toLowerCase() if (value === 'start') { finish() return } else if (value === 'mellon') { triggerEgg('moria') } else if (value === 'you shall not pass') { triggerEgg('balrog') } else if (value === 'iddqd') { triggerEgg('iddqd') } else if (value === 'idkfa') { triggerEgg('idkfa') } else if (value === 'reboot') { onReboot() return } setCmd('') } return (
{BOOT_LINES.slice(0, visibleBoot).map((line, idx) => (
{line || ' '}
))}
{phase !== 'boot' && (
{GREETING_LINES.slice(0, visibleGreet).map((line, idx) => (
{line}
))}
)} {phase === 'prompt' && (
{eggView === 'none' ? (
➤ ~ { setCmd(e.target.value); resetIdleTimer() }} onKeyDown={handleInputKeyDown} autoComplete="off" spellCheck={false} aria-label="boot command input" disabled={eggBusy} />
type start to enter — speak, friend, and enter…
) : (
{EGG_ART[eggView]}
{EGG_CAPTIONS[eggView]}
)}
)}
{phase === 'prompt' ? 'auto-launching soon if idle' : 'press any key to skip animation'}
) }