From f56a30ee02d12d70e410844b5e6291ac1a916a00 Mon Sep 17 00:00:00 2001 From: Chneemann Date: Tue, 28 Jul 2026 09:07:42 +0200 Subject: [PATCH] feat: add playSudoEasterEgg terminal simulation and hook into command palette --- src/lib/paletteCommands.ts | 47 ++++++++++++++----- src/lib/playSudoEasterEgg.ts | 91 ++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 src/lib/playSudoEasterEgg.ts diff --git a/src/lib/paletteCommands.ts b/src/lib/paletteCommands.ts index d49929f..924c213 100644 --- a/src/lib/paletteCommands.ts +++ b/src/lib/paletteCommands.ts @@ -1,3 +1,5 @@ +import { playSudoEasterEgg } from "./playSudoEasterEgg"; + /** * Command item structure for the Cmd+K palette */ @@ -18,7 +20,7 @@ export const getCommands = ( ): CommandItem[] => [ { id: "copy-email", - label: copied ? "Email Copied! ✓" : "Copy Email (dev@andre-kempf.com)", + label: copied ? "Email Copied!" : "Copy Email (dev@andre-kempf.com)", category: "Quick Actions", icon: copied ? "✓" : "✉️", action: () => { @@ -29,15 +31,15 @@ export const getCommands = ( }, { id: "download-cv", - label: "Download Resume / CV (PDF)", + label: "Download CV (PDF)", category: "Quick Actions", icon: "📄", action: () => { - const link = document.createElement("a"); - link.href = - "https://andre-kempf.com/assets/downloads/Andre_Kempf_Lebenslauf_2025.pdf"; - link.download = "Andre_Kempf_Lebenslauf.pdf"; - link.click(); + window.open( + "/assets/downloads/Andre_Kempf_Lebenslauf.pdf", + "_blank", + "noopener,noreferrer", + ); }, }, { @@ -55,7 +57,11 @@ export const getCommands = ( category: "Social / Links", icon: "🏔️", action: () => { - window.open("https://codeberg.org/Chneemann", "_blank"); + window.open( + "https://codeberg.org/Chneemann", + "_blank", + "noopener,noreferrer", + ); }, }, { @@ -64,7 +70,11 @@ export const getCommands = ( category: "Social / Links", icon: "🐙", action: () => { - window.open("https://github.com/andre-kempf", "_blank"); + window.open( + "https://github.com/andre-kempf", + "_blank", + "noopener,noreferrer", + ); }, }, { @@ -73,7 +83,11 @@ export const getCommands = ( category: "Social / Links", icon: "💼", action: () => { - window.open("https://linkedin.com/in/andre-kempf", "_blank"); + window.open( + "https://linkedin.com/in/andre-kempf", + "_blank", + "noopener,noreferrer", + ); }, }, { @@ -82,7 +96,18 @@ export const getCommands = ( category: "Social / Links", icon: "💻", action: () => { - window.open("https://codeberg.org/Chneemann/portfolio", "_blank"); + window.open( + "https://codeberg.org/Chneemann/portfolio", + "_blank", + "noopener,noreferrer", + ); }, }, + { + id: "sudo-egg", + label: "sudo rm -rf --no-preserve-root /", + category: "System & Info", + icon: "💀", + action: playSudoEasterEgg, + }, ]; diff --git a/src/lib/playSudoEasterEgg.ts b/src/lib/playSudoEasterEgg.ts new file mode 100644 index 0000000..3fc861c --- /dev/null +++ b/src/lib/playSudoEasterEgg.ts @@ -0,0 +1,91 @@ +/** + * Triggers a simulated terminal kernel panic overlay ("sudo rm -rf"). + * Appends a full-screen DOM overlay, streams logs with delayed timeouts, and cleans up automatically. + */ +export function playSudoEasterEgg() { + // Create full-screen terminal overlay element + const flashOverlay = document.createElement("div"); + flashOverlay.className = + "fixed inset-0 z-[99999] bg-black text-xs font-mono flex flex-col justify-between p-6 md:p-12 selection:bg-red-500 selection:text-white select-none backdrop-blur-xl animate-in fade-in duration-75 overflow-hidden"; + + flashOverlay.innerHTML = ` +
+ + `; + + document.body.appendChild(flashOverlay); + + const logsContainer = flashOverlay.querySelector("#terminal-logs"); + const footer = flashOverlay.querySelector("#terminal-footer"); + + // Helper to append formatted log HTML strings to the container + const appendLog = (htmlString: string) => { + if (!logsContainer) return; + const temp = document.createElement("div"); + temp.innerHTML = htmlString.trim(); + if (temp.firstElementChild) + logsContainer.appendChild(temp.firstElementChild); + }; + + // Timed output lines simulating system destruction and resolution + const lines = [ + { + html: `

[ 0.000000] Linux kernel init sequence started...

`, + delay: 100, + }, + { + html: `

root@andre-kempf-portfolio:~# sudo rm -rf --no-preserve-root /

`, + delay: 400, + }, + { + html: `

rm: unlinking '/etc/shadow'...

`, + delay: 700, + }, + { + html: `

rm: unlinking '/boot/vmlinuz-6.8.0-generic'...

`, + delay: 900, + }, + { + html: `

rm: unlinking '/var/www/portfolio/index.html'...

`, + delay: 1100, + }, + { + html: `

Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009

`, + delay: 1500, + }, + { + html: ` +
+

+ 🚨 CRITICAL SECURITY ALERT: HARD DRIVE WIPED +

+

+ Wiping process executed on /dev/nvme0n1. All system files, database records, and site assets have been purged. +

+

+ [Incident logged. IP & Session details sent to administrator.] +

+
`, + delay: 2000, + }, + { + html: `

✓ ...Just kidding! System is write-protected. Relax!

`, + delay: 5200, + }, + ]; + + // Stream terminal lines sequentially + lines.forEach(({ html, delay }) => setTimeout(() => appendLog(html), delay)); + + // Show footer warning message + setTimeout(() => footer?.classList.remove("opacity-0"), 2200); + + // Fade out and remove overlay element from DOM + setTimeout(() => { + flashOverlay.classList.add("animate-out", "fade-out", "duration-500"); + setTimeout(() => flashOverlay.remove(), 500); + }, 7500); +}