@@ -246,12 +246,19 @@ const Game: React.FC = () => { |
| 246 | 246 | </div> |
| 247 | 247 | |
| 248 | 248 | {/* Floating Terminal - Top Left */} |
| 249 | | - <div className={`absolute top-4 left-4 bg-gray-800/95 backdrop-blur-sm rounded-lg shadow-2xl border border-gray-700 transition-all duration-300 z-30 ${ |
| 250 | | - terminalMinimized ? 'w-80' : 'w-[500px]' |
| 249 | + <div className={`absolute top-4 left-4 bg-gray-900 rounded-lg shadow-2xl border border-gray-800 transition-all duration-300 z-30 ${ |
| 250 | + terminalMinimized ? 'w-80' : 'w-[700px]' |
| 251 | 251 | }`}> |
| 252 | 252 | {/* Terminal Header */} |
| 253 | | - <div className="flex items-center justify-between bg-gray-700 px-4 py-2 rounded-t-lg"> |
| 254 | | - <h3 className="text-sm font-semibold text-gray-300">Terminal</h3> |
| 253 | + <div className="flex items-center justify-between bg-gray-800 px-4 py-2 rounded-t-lg border-b border-gray-700"> |
| 254 | + <div className="flex items-center gap-2"> |
| 255 | + <div className="flex gap-1.5"> |
| 256 | + <div className="w-3 h-3 bg-red-500 rounded-full"></div> |
| 257 | + <div className="w-3 h-3 bg-yellow-500 rounded-full"></div> |
| 258 | + <div className="w-3 h-3 bg-green-500 rounded-full"></div> |
| 259 | + </div> |
| 260 | + <h3 className="text-sm font-medium text-gray-300 ml-2">bash</h3> |
| 261 | + </div> |
| 255 | 262 | <button |
| 256 | 263 | onClick={() => setTerminalMinimized(!terminalMinimized)} |
| 257 | 264 | className="text-gray-400 hover:text-white transition" |
@@ -262,52 +269,68 @@ const Game: React.FC = () => { |
| 262 | 269 | |
| 263 | 270 | {/* Terminal Content */} |
| 264 | 271 | {!terminalMinimized && ( |
| 265 | | - <> |
| 266 | | - <div |
| 267 | | - ref={terminalRef} |
| 268 | | - className="bg-black text-green-400 p-3 font-mono text-xs h-[300px] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-700" |
| 269 | | - > |
| 270 | | - {commandHistory.map((entry, index) => ( |
| 271 | | - <div key={index} className="mb-2"> |
| 272 | | - <div className="text-gray-400"> |
| 273 | | - {entry.command.startsWith('Game started!') ? ( |
| 274 | | - <span className="text-yellow-400">{entry.command}</span> |
| 275 | | - ) : ( |
| 276 | | - <>$ {entry.command}</> |
| 277 | | - )} |
| 278 | | - </div> |
| 279 | | - <div className={entry.success ? 'text-green-400' : 'text-red-400'}> |
| 272 | + <div |
| 273 | + ref={terminalRef} |
| 274 | + className="bg-black p-4 font-mono text-base h-[350px] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-700" |
| 275 | + onClick={() => inputRef.current?.focus()} |
| 276 | + > |
| 277 | + {commandHistory.map((entry, index) => ( |
| 278 | + <div key={index} className="mb-1"> |
| 279 | + <div className="flex items-start"> |
| 280 | + <span className="text-green-400">groundskeeper@molehill</span> |
| 281 | + <span className="text-gray-400 mx-1">::</span> |
| 282 | + <span className="text-blue-400">{entry.command.startsWith('Hunt started!') ? '~' : gameState.tree?.player_location || '~'}</span> |
| 283 | + <span className="text-gray-400 ml-1">$</span> |
| 284 | + <span className={`ml-2 ${entry.command.startsWith('Hunt started!') ? 'text-yellow-400' : 'text-gray-300'}`}> |
| 285 | + {entry.command.startsWith('Hunt started!') ? '' : entry.command} |
| 286 | + </span> |
| 287 | + </div> |
| 288 | + {entry.output && ( |
| 289 | + <div className={`${entry.success ? 'text-gray-300' : 'text-red-400'} ml-0 mt-1`}> |
| 280 | 290 | {entry.output.split('\n').map((line, i) => ( |
| 281 | | - <div key={i} className="ml-2">{line}</div> |
| 291 | + <div key={i}>{line}</div> |
| 282 | 292 | ))} |
| 283 | 293 | </div> |
| 294 | + )} |
| 295 | + </div> |
| 296 | + ))} |
| 297 | + |
| 298 | + {/* Current input line */} |
| 299 | + <div className="flex items-start"> |
| 300 | + <span className="text-green-400">groundskeeper@molehill</span> |
| 301 | + <span className="text-gray-400 mx-1">::</span> |
| 302 | + <span className="text-blue-400">{gameState.tree?.player_location || '~'}</span> |
| 303 | + <span className="text-gray-400 ml-1">$</span> |
| 304 | + <form onSubmit={handleSubmit} className="flex-1 ml-2"> |
| 305 | + <div className="relative"> |
| 306 | + <input |
| 307 | + ref={inputRef} |
| 308 | + type="text" |
| 309 | + value={command} |
| 310 | + onChange={(e) => setCommand(e.target.value)} |
| 311 | + disabled={executing || gameState.tree?.is_completed} |
| 312 | + className="w-full bg-transparent text-gray-300 outline-none caret-transparent" |
| 313 | + placeholder="" |
| 314 | + autoFocus |
| 315 | + spellCheck={false} |
| 316 | + autoComplete="off" |
| 317 | + autoCorrect="off" |
| 318 | + autoCapitalize="off" |
| 319 | + /> |
| 320 | + {/* Blinking cursor */} |
| 321 | + <span |
| 322 | + className="absolute text-gray-300 pointer-events-none" |
| 323 | + style={{ |
| 324 | + left: `${command.length * 0.6}em`, |
| 325 | + animation: 'blink 1s step-end infinite' |
| 326 | + }} |
| 327 | + > |
| 328 | + _ |
| 329 | + </span> |
| 284 | 330 | </div> |
| 285 | | - ))} |
| 331 | + </form> |
| 286 | 332 | </div> |
| 287 | | - |
| 288 | | - <form onSubmit={handleSubmit} className="border-t border-gray-700"> |
| 289 | | - <div className="flex bg-gray-900"> |
| 290 | | - <span className="bg-gray-800 px-3 py-2 text-green-400 font-mono text-sm">$</span> |
| 291 | | - <input |
| 292 | | - ref={inputRef} |
| 293 | | - type="text" |
| 294 | | - value={command} |
| 295 | | - onChange={(e) => setCommand(e.target.value)} |
| 296 | | - disabled={executing || gameState.tree.is_completed} |
| 297 | | - className="flex-1 px-3 py-2 bg-gray-900 text-green-400 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500 font-mono placeholder-gray-600" |
| 298 | | - placeholder="cd, ls, pwd, help, killall moles" |
| 299 | | - autoFocus |
| 300 | | - /> |
| 301 | | - <button |
| 302 | | - type="submit" |
| 303 | | - disabled={executing || gameState.tree.is_completed} |
| 304 | | - className="px-4 py-2 bg-blue-600 text-white text-sm hover:bg-blue-700 disabled:bg-gray-700 disabled:text-gray-500 transition" |
| 305 | | - > |
| 306 | | - {executing ? '...' : 'Run'} |
| 307 | | - </button> |
| 308 | | - </div> |
| 309 | | - </form> |
| 310 | | - </> |
| 333 | + </div> |
| 311 | 334 | )} |
| 312 | 335 | </div> |
| 313 | 336 | |