inputRef.current?.focus()}
+ >
+ {/* CRT scanlines */}
+ {theme === "dark" && (
+
-
-
- {output.map((line, index) => (
-
- {line.split("\n").map((text, idx) => (
-
- {text}
-
-
+ )}
+
+ {/* HEADER */}
+
+
+
+ {["#ff5f57", "#febc2e", "#28c840"].map((c, i) => (
+
))}
-
- ))}
+
+
+ satyam@portfolio
+
+
+
-
-
- root@kali
-
- setCommand(e.target.value)}
- onKeyDown={handleCommand}
+
+ {/* SCROLLABLE OUTPUT */}
+
-
-
-
- );
-};
+ >
+ {output.map((line, i) => {
+ if (line.type === "boot")
+ return (
+
+ {line.text === "" ?
: {"› "}{line.text}}
+
+ );
+ if (line.type === "cmd")
+ return (
+
+ root
+ @
+ kali
+ :~$
+
+ {line.text}
+
+
+ );
+ if (line.type === "out")
+ return (
+
+ {line.lines.map((l, j) => renderLine(l, j))}
+
+ );
+ return null;
+ })}
+
+
+
+ {/* STICKY INPUT */}
+
+
+ root
+
+
+ @
+
+
+ kali
+
+
+ :~$
+
+
+ setCommand(e.target.value)}
+ onKeyDown={handleKeyDown}
+ onFocus={() => setFocused(true)}
+ onBlur={() => setFocused(false)}
+ disabled={!booted}
+ autoComplete="off"
+ spellCheck={false}
+ style={{
+ flex: 1,
+ background: "transparent",
+ border: "none",
+ outline: "none",
+ color: t.text,
+ fontFamily: "inherit",
+ fontSize: fontSize,
+ caretColor: "transparent",
+ letterSpacing: "0.02em",
+ minWidth: 0,
+ padding: 0,
+ }}
+ />
+ {booted && focused && }
+
+
-export default Terminal;
+ {/* KEYBOARD HINTS - Hidden on mobile, shown on larger screens */}
+ {!isMobile && (
+
+ {[
+ ["TAB", "autocomplete"],
+ ["↑↓", "history"],
+ ["ENTER", "execute"],
+ ].map(([key, label]) => (
+
+
+ {key}
+
+ {label}
+
+ ))}
+
+ )}
+
+ >
+ );
+}
\ No newline at end of file