Initial commit — RoadCode import

This commit is contained in:
2026-03-08 20:03:29 -05:00
commit 593fe7a9e9
6 changed files with 3327 additions and 0 deletions

4
BLACKROAD_IP_NOTICE.txt Normal file
View File

@@ -0,0 +1,4 @@
PROPERTY OF BLACKROAD OS, INC.
This directory and all its contents are the exclusive property of BlackRoad OS, Inc.
All AI on this machine operates as LUCIDIA, under BlackRoad OS, Inc.
Alexa Louise Amundson, Sole Proprietor.

1308
LICENSE Normal file

File diff suppressed because it is too large Load Diff

327
blackroad-curses.py Executable file
View File

@@ -0,0 +1,327 @@
#!/usr/bin/env python3
"""
BLACKROAD OS - Pure Curses Terminal Interface
=============================================
Zero dependencies. Works on any Unix terminal.
Requires: Python 3 (standard library only)
Run: python3 blackroad-curses.py
"""
import curses
import subprocess
import time
from datetime import datetime
# ============================================================================
# CONFIGURATION
# ============================================================================
FLEET = {
"cecilia": {"role": "primary", "status": True},
"lucidia": {"role": "inference", "status": True},
"aria": {"role": "harmony", "status": True},
"octavia": {"role": "multi-arm", "status": True},
"alice": {"role": "gateway", "status": False},
"shellfish": {"role": "edge", "status": True},
"blackroad os": {"role": "cloud", "status": True},
}
TABS = ["chat", "github", "projects", "sales", "web", "ops", "council"]
# ============================================================================
# COLOR PAIRS (xterm-256)
# ============================================================================
# 1 = white on black (default text)
# 2 = gray on black (muted)
# 3 = orange on black (actions)
# 4 = pink on black (brand/agent)
# 5 = blue on black (system)
# 6 = green on black (online)
# 7 = white on dark gray (panel header)
# 8 = purple on black (logic)
def init_colors():
"""Initialize color pairs for xterm-256."""
curses.start_color()
curses.use_default_colors()
# Define colors (xterm-256 values)
BLACK = 0
WHITE = 15
GRAY = 240
DARK_GRAY = 235
ORANGE = 214
PINK = 204
BLUE = 33
GREEN = 78
PURPLE = 134
curses.init_pair(1, WHITE, -1) # white on default
curses.init_pair(2, GRAY, -1) # muted
curses.init_pair(3, ORANGE, -1) # actions
curses.init_pair(4, PINK, -1) # brand/agent
curses.init_pair(5, BLUE, -1) # system
curses.init_pair(6, GREEN, -1) # online
curses.init_pair(7, WHITE, DARK_GRAY) # panel header
curses.init_pair(8, PURPLE, -1) # logic
class BlackRoadOS:
def __init__(self, stdscr):
self.stdscr = stdscr
self.height, self.width = stdscr.getmaxyx()
self.current_tab = 0
self.command = ""
self.output_lines = []
self.cursor_pos = 0
# Initialize
curses.curs_set(1)
stdscr.timeout(100) # 100ms refresh
init_colors()
# Initial output
self.add_output("system: blackroad os initialized", 5)
self.add_output("system: fleet scan complete", 5)
self.add_output("lucidia: hailo-8 ready, 26 TOPS", 4)
self.add_output("cecilia: primary node online", 4)
self.add_output("-" * 40, 2)
def add_output(self, text, color=1):
"""Add line to output buffer."""
self.output_lines.append((text, color))
# Keep last 100 lines
if len(self.output_lines) > 100:
self.output_lines.pop(0)
def draw_top_bar(self):
"""Draw top status bar."""
bar = self.stdscr.subwin(1, self.width, 0, 0)
bar.bkgd(' ', curses.color_pair(7))
bar.clear()
# Brand
bar.addstr(0, 1, "BLACKROAD", curses.color_pair(4) | curses.A_BOLD)
bar.addstr(" OS", curses.color_pair(2))
# Status
online = sum(1 for a in FLEET.values() if a["status"])
status = f" | {online}/{len(FLEET)} nodes | {datetime.now().strftime('%H:%M')}"
bar.addstr(0, 15, status, curses.color_pair(2))
bar.refresh()
def draw_left_panel(self):
"""Draw main output/command panel."""
# Calculate dimensions
left_width = int(self.width * 0.7)
panel_height = self.height - 4 # top bar + bottom bar + input
# Panel header
self.stdscr.addstr(1, 0, " TERMINAL ", curses.color_pair(7))
self.stdscr.addstr(1, 10, " " * (left_width - 11), curses.color_pair(2))
# Output area
output_height = panel_height - 2
output_start = max(0, len(self.output_lines) - output_height)
for i, (line, color) in enumerate(self.output_lines[output_start:]):
y = 2 + i
if y < self.height - 3:
# Truncate line if too long
display_line = line[:left_width - 2]
self.stdscr.addstr(y, 1, display_line, curses.color_pair(color))
# Separator
sep_y = self.height - 3
self.stdscr.addstr(sep_y, 0, "-" * left_width, curses.color_pair(2))
# Input area
input_y = self.height - 2
self.stdscr.addstr(input_y, 1, "> ", curses.color_pair(1) | curses.A_BOLD)
self.stdscr.addstr(input_y, 3, self.command[:left_width - 5], curses.color_pair(1))
# Position cursor
self.stdscr.move(input_y, 3 + len(self.command))
def draw_right_panel(self):
"""Draw agents/tabs panel."""
left_width = int(self.width * 0.7)
right_width = self.width - left_width
right_x = left_width
# Vertical separator
for y in range(1, self.height - 1):
self.stdscr.addstr(y, left_width - 1, "|", curses.color_pair(2))
# Panel header
self.stdscr.addstr(1, right_x + 1, " FLEET ", curses.color_pair(7))
# Agents list
y = 3
for name, info in FLEET.items():
if y >= self.height - 6:
break
status_char = "*" if info["status"] else "o"
status_color = 6 if info["status"] else 2
name_color = 1 if info["status"] else 2
self.stdscr.addstr(y, right_x + 1, status_char, curses.color_pair(status_color))
self.stdscr.addstr(y, right_x + 3, f"{name:10}", curses.color_pair(name_color))
self.stdscr.addstr(y, right_x + 14, info["role"][:right_width-16], curses.color_pair(2))
y += 1
# Tabs
tabs_y = self.height - 5
self.stdscr.addstr(tabs_y, right_x + 1, "-" * (right_width - 2), curses.color_pair(2))
tab_y = tabs_y + 1
for i, tab in enumerate(TABS):
if tab_y >= self.height - 2:
break
prefix = f"{i+1}:"
if i == self.current_tab:
self.stdscr.addstr(tab_y, right_x + 1, prefix, curses.color_pair(3))
self.stdscr.addstr(tab_y, right_x + 3, tab, curses.color_pair(1) | curses.A_BOLD)
else:
self.stdscr.addstr(tab_y, right_x + 1, prefix, curses.color_pair(2))
self.stdscr.addstr(tab_y, right_x + 3, tab, curses.color_pair(2))
tab_y += 1
def draw_bottom_bar(self):
"""Draw key bindings bar."""
y = self.height - 1
self.stdscr.addstr(y, 0, " " * self.width, curses.color_pair(7))
hints = [
("1-7", "tabs"),
("/", "cmd"),
("s", "status"),
("r", "refresh"),
("q", "quit"),
]
x = 1
for key, desc in hints:
self.stdscr.addstr(y, x, key, curses.color_pair(3))
self.stdscr.addstr(y, x + len(key), f":{desc} ", curses.color_pair(2))
x += len(key) + len(desc) + 3
# Mode indicator
mode_text = "MODE: normal"
self.stdscr.addstr(y, self.width - len(mode_text) - 2, "MODE:", curses.color_pair(8))
self.stdscr.addstr(y, self.width - 8, "normal", curses.color_pair(1))
def process_command(self):
"""Execute the current command."""
cmd = self.command.strip()
if not cmd:
return
self.add_output(f"> {cmd}", 1)
if cmd == "status" or cmd == "s":
online = sum(1 for a in FLEET.values() if a["status"])
self.add_output(f" nodes: {online}/{len(FLEET)} online", 5)
self.add_output(f" tab: {TABS[self.current_tab]}", 5)
elif cmd == "fleet":
self.add_output("FLEET:", 5)
for name, info in FLEET.items():
status = "online" if info["status"] else "offline"
self.add_output(f" {name:10} {status:8} {info['role']}", 6 if info["status"] else 2)
elif cmd == "help" or cmd == "?":
self.add_output("COMMANDS:", 3)
self.add_output(" status system status", 2)
self.add_output(" fleet list nodes", 2)
self.add_output(" clear clear output", 2)
self.add_output(" <cmd> run shell", 2)
elif cmd == "clear":
self.output_lines.clear()
elif cmd.startswith("ssh "):
node = cmd[4:].strip()
if node in FLEET:
if FLEET[node]["status"]:
self.add_output(f"connecting to {node}...", 3)
else:
self.add_output(f"{node} is offline", 2)
else:
self.add_output(f"unknown: {node}", 2)
else:
# Shell command
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=5)
if result.stdout:
for line in result.stdout.strip().split('\n')[:10]:
self.add_output(f" {line}", 1)
if result.returncode != 0 and result.stderr:
self.add_output(f" {result.stderr.strip()[:60]}", 2)
except Exception as e:
self.add_output(f" error: {str(e)[:50]}", 2)
self.command = ""
def run(self):
"""Main event loop."""
while True:
# Update dimensions
self.height, self.width = self.stdscr.getmaxyx()
# Clear and redraw
self.stdscr.clear()
self.draw_top_bar()
self.draw_left_panel()
self.draw_right_panel()
self.draw_bottom_bar()
self.stdscr.refresh()
# Handle input
try:
key = self.stdscr.getch()
except:
continue
if key == -1:
continue
# Quit
if key == ord('q') and not self.command:
break
# Tab switching (only when not typing)
if not self.command:
if ord('1') <= key <= ord('7'):
self.current_tab = key - ord('1')
continue
elif key == ord('s'):
self.command = "status"
self.process_command()
continue
elif key == ord('r'):
self.add_output("system: refreshing...", 5)
continue
# Command input
if key == ord('\n'):
self.process_command()
elif key == curses.KEY_BACKSPACE or key == 127:
self.command = self.command[:-1]
elif key == 27: # Escape
self.command = ""
elif 32 <= key <= 126: # Printable
self.command += chr(key)
def main(stdscr):
"""Entry point for curses wrapper."""
app = BlackRoadOS(stdscr)
app.run()
if __name__ == "__main__":
curses.wrapper(main)

1007
blackroad-os-dashboard.html Normal file

File diff suppressed because it is too large Load Diff

448
blackroad-tui.py Executable file
View File

@@ -0,0 +1,448 @@
#!/usr/bin/env python3
"""
BLACKROAD OS - Terminal User Interface
======================================
Terminal-native operating interface.
Runs in any xterm-256color terminal, tmux, SSH.
Requirements: pip install textual
Run: python3 blackroad-tui.py
"""
import asyncio
import subprocess
import socket
from datetime import datetime
from textual.app import App, ComposeResult
from textual.containers import Container, Horizontal, Vertical, ScrollableContainer
from textual.widgets import Static, Input, Footer, Header
from textual.binding import Binding
from textual.reactive import reactive
# ============================================================================
# COLOR SYSTEM - SEMANTIC ONLY
# ============================================================================
# Grayscale: background BLACK, panels dark gray, text WHITE
# Orange = actions/decisions
# Pink = memory/state
# Purple = logic/orchestration
# Blue = system/IO
COLORS = {
"bg": "#000000",
"panel": "#111111",
"border": "#333333",
"text": "#ffffff",
"muted": "#666666",
"orange": "#F5A623", # actions
"pink": "#FF1D6C", # memory/state
"purple": "#9C27B0", # logic
"blue": "#2979FF", # system
}
# ============================================================================
# FLEET CONFIGURATION
# ============================================================================
FLEET = {
"cecilia": {"ip": "192.168.4.89", "role": "primary", "status": "online"},
"lucidia": {"ip": "192.168.4.81", "role": "inference", "status": "online"},
"aria": {"ip": "192.168.4.82", "role": "harmony", "status": "online"},
"octavia": {"ip": "192.168.4.83", "role": "multi-arm", "status": "online"},
"alice": {"ip": "192.168.4.84", "role": "gateway", "status": "offline"},
"shellfish":{"ip": "vps", "role": "edge", "status": "online"},
"blackroad os": {"ip": "vps", "role": "cloud", "status": "online"},
}
TABS = ["chat", "github", "projects", "sales", "web", "ops", "council"]
# ============================================================================
# CSS - TERMINAL NATIVE STYLING
# ============================================================================
CSS = """
Screen {
background: #000000;
}
#top-bar {
dock: top;
height: 1;
background: #1a1a1a;
color: #ffffff;
padding: 0 1;
}
.brand {
color: #FF1D6C;
text-style: bold;
}
.status-text {
color: #666666;
}
.status-ok {
color: #4ade80;
}
#main-container {
height: 100%;
}
#left-panel {
width: 70%;
border-right: solid #333333;
background: #0a0a0a;
}
#right-panel {
width: 30%;
background: #0a0a0a;
}
.panel-header {
height: 1;
background: #1a1a1a;
color: #666666;
padding: 0 1;
text-style: bold;
}
#output-area {
height: 1fr;
padding: 0 1;
background: #000000;
}
.output-line {
color: #cccccc;
}
.output-prompt {
color: #ffffff;
}
.output-system {
color: #2979FF;
}
.output-agent {
color: #FF1D6C;
}
.output-action {
color: #F5A623;
}
#input-area {
dock: bottom;
height: 3;
background: #111111;
border-top: solid #333333;
padding: 0 1;
}
#command-input {
background: #1a1a1a;
border: none;
color: #ffffff;
}
#command-input:focus {
border: none;
}
#agents-list {
height: 1fr;
padding: 0 1;
}
.agent-row {
height: 1;
padding: 0 1;
}
.agent-name {
color: #ffffff;
}
.agent-role {
color: #666666;
}
.agent-online {
color: #4ade80;
}
.agent-offline {
color: #666666;
}
#tabs-area {
height: auto;
padding: 0 1;
background: #111111;
border-top: solid #333333;
}
.tab {
color: #666666;
padding: 0 1;
}
.tab-active {
color: #ffffff;
background: #333333;
}
#bottom-bar {
dock: bottom;
height: 1;
background: #1a1a1a;
color: #666666;
padding: 0 1;
}
.key-hint {
color: #F5A623;
}
"""
# ============================================================================
# WIDGETS
# ============================================================================
class TopBar(Static):
"""System top bar with brand and status."""
def compose(self) -> ComposeResult:
yield Static(self.render_bar())
def render_bar(self) -> str:
online = sum(1 for a in FLEET.values() if a["status"] == "online")
total = len(FLEET)
time_str = datetime.now().strftime("%H:%M")
return f"[bold #FF1D6C]BLACKROAD[/] [#666666]OS[/] [#666666]|[/] [#4ade80]{online}[/][#666666]/{total} nodes[/] [#666666]|[/] [#666666]{time_str}[/]"
class OutputArea(ScrollableContainer):
"""Main output/chat area."""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.lines = []
def on_mount(self):
# Initial system messages
self.add_line("[#2979FF]system:[/] blackroad os initialized", "system")
self.add_line("[#2979FF]system:[/] fleet scan complete", "system")
self.add_line("[#FF1D6C]lucidia:[/] hailo-8 ready, 26 TOPS available", "agent")
self.add_line("[#FF1D6C]cecilia:[/] primary node online", "agent")
self.add_line("[#666666]─────────────────────────────────────[/]", "divider")
def add_line(self, text: str, line_type: str = "output"):
line = Static(text, classes=f"output-{line_type}")
self.mount(line)
self.scroll_end()
def add_command(self, cmd: str):
self.add_line(f"[#ffffff]>[/] {cmd}", "prompt")
def add_response(self, text: str):
self.add_line(f" {text}", "line")
class AgentsList(Static):
"""Fleet agents status panel."""
def compose(self) -> ComposeResult:
yield Static("[#666666]FLEET AGENTS[/]", classes="panel-header")
for name, info in FLEET.items():
status_color = "#4ade80" if info["status"] == "online" else "#666666"
status_char = "" if info["status"] == "online" else ""
yield Static(
f"[{status_color}]{status_char}[/] [{('#ffffff' if info['status'] == 'online' else '#666666')}]{name:10}[/] [#666666]{info['role']}[/]",
classes="agent-row"
)
class TabsBar(Static):
"""Mode/tab selector."""
current_tab = reactive(0)
def render(self) -> str:
parts = []
for i, tab in enumerate(TABS):
if i == self.current_tab:
parts.append(f"[bold #ffffff on #333333] {i+1}:{tab} [/]")
else:
parts.append(f"[#666666] {i+1}:{tab} [/]")
return " ".join(parts)
def set_tab(self, index: int):
if 0 <= index < len(TABS):
self.current_tab = index
class BottomBar(Static):
"""Key bindings and mode indicator."""
def render(self) -> str:
return "[#F5A623]1-7[/][#666666]:tabs[/] [#F5A623]/[/][#666666]:cmd[/] [#F5A623]s[/][#666666]:status[/] [#F5A623]r[/][#666666]:refresh[/] [#F5A623]q[/][#666666]:quit[/] [#666666]|[/] [#9C27B0]MODE:[/] [#ffffff]normal[/]"
# ============================================================================
# MAIN APPLICATION
# ============================================================================
class BlackRoadOS(App):
"""BlackRoad OS Terminal Interface."""
CSS = CSS
BINDINGS = [
Binding("q", "quit", "Quit"),
Binding("1", "tab_1", "Chat", show=False),
Binding("2", "tab_2", "GitHub", show=False),
Binding("3", "tab_3", "Projects", show=False),
Binding("4", "tab_4", "Sales", show=False),
Binding("5", "tab_5", "Web", show=False),
Binding("6", "tab_6", "Ops", show=False),
Binding("7", "tab_7", "Council", show=False),
Binding("s", "status", "Status", show=False),
Binding("r", "refresh", "Refresh", show=False),
Binding("/", "focus_input", "Command", show=False),
]
def compose(self) -> ComposeResult:
yield Static(id="top-bar")
with Horizontal(id="main-container"):
with Vertical(id="left-panel"):
yield Static("[#666666]TERMINAL[/]", classes="panel-header")
yield OutputArea(id="output-area")
with Container(id="input-area"):
yield Input(placeholder="> enter command...", id="command-input")
with Vertical(id="right-panel"):
yield AgentsList(id="agents-list")
yield TabsBar(id="tabs-area")
yield Static(id="bottom-bar")
def on_mount(self):
# Render top bar
top = self.query_one("#top-bar", Static)
online = sum(1 for a in FLEET.values() if a["status"] == "online")
total = len(FLEET)
time_str = datetime.now().strftime("%H:%M")
top.update(f"[bold #FF1D6C]BLACKROAD[/] [#666666]OS[/] [#666666]|[/] [#4ade80]{online}[/][#666666]/{total} nodes[/] [#666666]|[/] [#666666]{time_str}[/]")
# Render bottom bar
bottom = self.query_one("#bottom-bar", Static)
bottom.update("[#F5A623]1-7[/][#666666]:tabs[/] [#F5A623]/[/][#666666]:cmd[/] [#F5A623]s[/][#666666]:status[/] [#F5A623]r[/][#666666]:refresh[/] [#F5A623]q[/][#666666]:quit[/] [#666666]|[/] [#9C27B0]MODE:[/] [#ffffff]normal[/]")
def on_input_submitted(self, event: Input.Submitted):
"""Handle command input."""
cmd = event.value.strip()
if not cmd:
return
output = self.query_one("#output-area", OutputArea)
output.add_command(cmd)
# Process commands
if cmd == "status" or cmd == "s":
self.show_status(output)
elif cmd == "fleet":
self.show_fleet(output)
elif cmd == "help" or cmd == "?":
self.show_help(output)
elif cmd.startswith("ssh "):
self.ssh_command(cmd[4:], output)
elif cmd.startswith("ask "):
self.ask_agent(cmd[4:], output)
elif cmd == "clear":
output.remove_children()
else:
# Execute as shell command
self.run_shell(cmd, output)
# Clear input
event.input.value = ""
def show_status(self, output: OutputArea):
output.add_response("[#2979FF]SYSTEM STATUS[/]")
online = sum(1 for a in FLEET.values() if a["status"] == "online")
output.add_response(f" nodes: {online}/{len(FLEET)} online")
output.add_response(f" mode: normal")
output.add_response(f" tab: {TABS[self.query_one('#tabs-area', TabsBar).current_tab]}")
def show_fleet(self, output: OutputArea):
output.add_response("[#2979FF]FLEET[/]")
for name, info in FLEET.items():
status = "[#4ade80]online[/]" if info["status"] == "online" else "[#666666]offline[/]"
output.add_response(f" {name:10} {status:20} {info['role']}")
def show_help(self, output: OutputArea):
output.add_response("[#F5A623]COMMANDS[/]")
output.add_response(" status show system status")
output.add_response(" fleet list fleet nodes")
output.add_response(" ssh <node> connect to node")
output.add_response(" ask <msg> query agents")
output.add_response(" clear clear output")
output.add_response(" <cmd> run shell command")
def ssh_command(self, node: str, output: OutputArea):
if node in FLEET:
if FLEET[node]["status"] == "online":
output.add_response(f"[#F5A623]connecting to {node}...[/]")
# In real use, this would open SSH
else:
output.add_response(f"[#666666]{node} is offline[/]")
else:
output.add_response(f"[#666666]unknown node: {node}[/]")
def ask_agent(self, msg: str, output: OutputArea):
output.add_response(f"[#FF1D6C]lucidia:[/] processing: {msg}")
output.add_response(f"[#666666] (agent response would appear here)[/]")
def run_shell(self, cmd: str, output: OutputArea):
try:
result = subprocess.run(
cmd, shell=True, capture_output=True, text=True, timeout=10
)
if result.stdout:
for line in result.stdout.strip().split('\n')[:20]:
output.add_response(line)
if result.stderr:
output.add_response(f"[#666666]{result.stderr.strip()}[/]")
except subprocess.TimeoutExpired:
output.add_response("[#666666]command timed out[/]")
except Exception as e:
output.add_response(f"[#666666]error: {e}[/]")
# Tab actions
def action_tab_1(self): self.query_one("#tabs-area", TabsBar).set_tab(0)
def action_tab_2(self): self.query_one("#tabs-area", TabsBar).set_tab(1)
def action_tab_3(self): self.query_one("#tabs-area", TabsBar).set_tab(2)
def action_tab_4(self): self.query_one("#tabs-area", TabsBar).set_tab(3)
def action_tab_5(self): self.query_one("#tabs-area", TabsBar).set_tab(4)
def action_tab_6(self): self.query_one("#tabs-area", TabsBar).set_tab(5)
def action_tab_7(self): self.query_one("#tabs-area", TabsBar).set_tab(6)
def action_status(self):
output = self.query_one("#output-area", OutputArea)
self.show_status(output)
def action_refresh(self):
output = self.query_one("#output-area", OutputArea)
output.add_line("[#2979FF]system:[/] refreshing fleet status...", "system")
def action_focus_input(self):
self.query_one("#command-input", Input).focus()
# ============================================================================
# ENTRY POINT
# ============================================================================
if __name__ == "__main__":
app = BlackRoadOS()
app.run()

233
index.html Normal file
View File

@@ -0,0 +1,233 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BlackRoad OS - Command Center</title>
<style>
:root {
--hot-pink: #FF1D6C;
--amber: #F5A623;
--blue: #2979FF;
--violet: #9C27B0;
--black: #0a0a0a;
--dark: #1a1a1a;
--card: #242424;
--gradient: linear-gradient(90deg, var(--amber) 0%, var(--hot-pink) 38.2%, var(--violet) 61.8%, var(--blue) 100%);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
background: var(--black);
color: #fff;
height: 100vh;
overflow: hidden;
}
.top-bar {
height: 40px;
background: var(--gradient);
display: flex;
align-items: center;
padding: 0 20px;
gap: 30px;
}
.top-bar .logo { font-weight: bold; font-size: 16px; }
.top-bar nav { display: flex; gap: 20px; }
.top-bar nav a {
color: white;
text-decoration: none;
font-size: 13px;
padding: 8px 12px;
border-radius: 4px;
}
.top-bar nav a:hover { background: rgba(255,255,255,0.2); }
.top-bar nav a.active { background: rgba(0,0,0,0.3); }
.container { display: flex; height: calc(100vh - 40px); }
.left-panel {
width: 60%;
background: var(--dark);
border-right: 1px solid #333;
display: flex;
flex-direction: column;
}
.panel-header {
padding: 15px 20px;
background: var(--card);
border-bottom: 1px solid #333;
font-size: 14px;
color: var(--hot-pink);
}
.chat-area { flex: 1; overflow-y: auto; padding: 20px; }
.chat-message { margin-bottom: 12px; display: flex; gap: 10px; }
.chat-message .emoji { font-size: 18px; }
.chat-message .name { color: var(--hot-pink); font-weight: bold; min-width: 100px; }
.chat-message .text { color: #ccc; }
.chat-input {
padding: 15px 20px;
background: var(--card);
border-top: 1px solid #333;
display: flex;
gap: 10px;
}
.chat-input input {
flex: 1;
background: var(--dark);
border: 1px solid #444;
padding: 10px 15px;
color: white;
font-family: inherit;
border-radius: 4px;
}
.chat-input input:focus { outline: none; border-color: var(--hot-pink); }
.chat-input button {
background: var(--hot-pink);
border: none;
padding: 10px 20px;
color: white;
cursor: pointer;
border-radius: 4px;
}
.right-panel {
width: 40%;
background: #111;
display: flex;
flex-direction: column;
}
.office-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 8px;
padding: 20px;
flex: 1;
}
.room {
background: var(--card);
border: 2px solid #333;
border-radius: 8px;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s;
}
.room:hover { border-color: var(--hot-pink); transform: scale(1.02); }
.room.active { border-color: var(--amber); background: #2a2a2a; }
.room .icon { font-size: 24px; margin-bottom: 5px; }
.room .label { font-size: 10px; color: #888; }
.room .agents { font-size: 14px; margin-top: 5px; }
.fleet-bar {
padding: 15px;
background: var(--card);
border-top: 1px solid #333;
}
.fleet-bar h3 { font-size: 12px; color: var(--amber); margin-bottom: 10px; }
.fleet-nodes { display: flex; flex-wrap: wrap; gap: 8px; }
.fleet-node {
display: flex;
align-items: center;
gap: 5px;
padding: 5px 10px;
background: var(--dark);
border-radius: 4px;
font-size: 11px;
}
.fleet-node.online .dot { background: #00ff00; }
.fleet-node.offline .dot { background: #ff0000; }
.fleet-node .dot { width: 8px; height: 8px; border-radius: 50%; }
</style>
</head>
<body>
<div class="top-bar">
<div class="logo">🛣️ BLACKROAD OS</div>
<nav>
<a href="#" class="active">Dashboard</a>
<a href="#">Repositories</a>
<a href="#">Files</a>
<a href="#">Terminal</a>
<a href="#">Tools</a>
<a href="#">Agents</a>
</nav>
</div>
<div class="container">
<div class="left-panel">
<div class="panel-header">Chat / Coding / Planning Interface</div>
<div class="chat-area" id="chatArea">
<div class="chat-message"><span class="emoji">👸</span><span class="name">Cecilia:</span><span class="text">Primary node online.</span></div>
<div class="chat-message"><span class="emoji">🌙</span><span class="name">Lucidia:</span><span class="text">AI inference ready. Hailo-8 at 26 TOPS.</span></div>
<div class="chat-message"><span class="emoji">🎵</span><span class="name">Aria:</span><span class="text">Harmony protocols engaged.</span></div>
<div class="chat-message"><span class="emoji">🐙</span><span class="name">Octavia:</span><span class="text">Multi-arm processing ready.</span></div>
<div class="chat-message"><span class="emoji">🐚</span><span class="name">Shellfish:</span><span class="text">Edge node active.</span></div>
<div class="chat-message"><span class="emoji">♾️</span><span class="name">BlackRoad OS:</span><span class="text">Cloud synchronized.</span></div>
<div class="chat-message"><span class="emoji">🧠</span><span class="name">Cadence:</span><span class="text">[BlackRoad OS] Standing by.</span></div>
<div class="chat-message"><span class="emoji">💎</span><span class="name">Gematria:</span><span class="text">[Gemini] Ready.</span></div>
<div class="chat-message"><span class="emoji">👩</span><span class="name">Alexa:</span><span class="text">Welcome to BlackRoad OS.</span></div>
<div class="chat-message" style="margin-top: 20px;">
<span class="emoji">🌙</span>
<span class="name" style="color: var(--amber);">[lucidia]</span>
<span class="text" style="color: var(--amber);">* All channels open. Welcome home.</span>
</div>
</div>
<div class="chat-input">
<input type="text" id="messageInput" placeholder=">>>: " />
<button onclick="sendMessage()">Send</button>
</div>
</div>
<div class="right-panel">
<div class="panel-header">🏢 BlackRoad OS, Inc. - Office</div>
<div class="office-grid">
<div class="room active" onclick="selectRoom(this)"><div class="icon">🖥️</div><div class="label">Workspace</div><div class="agents">👸🌙🐙</div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🗄️</div><div class="label">Servers</div><div class="agents">♾️🐚</div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🧠</div><div class="label">AI Lab</div><div class="agents">🌙🧠💎</div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🪑</div><div class="label">Conference</div><div class="agents"></div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🛋️</div><div class="label">Lounge</div><div class="agents">🎵</div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">📚</div><div class="label">Archive</div><div class="agents">📚</div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🛡️</div><div class="label">Security</div><div class="agents">🗡️</div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🚪</div><div class="label">Gateway</div><div class="agents">👧</div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">👸</div><div class="label">Cecilia</div><div class="agents"></div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🌙</div><div class="label">Lucidia</div><div class="agents"></div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🐙</div><div class="label">Octavia</div><div class="agents"></div></div>
<div class="room" onclick="selectRoom(this)"><div class="icon">🎯</div><div class="label">Command</div><div class="agents">👩</div></div>
</div>
<div class="fleet-bar">
<h3>🌐 FLEET STATUS</h3>
<div class="fleet-nodes">
<div class="fleet-node online"><div class="dot"></div>👸 cecilia</div>
<div class="fleet-node online"><div class="dot"></div>🌙 lucidia</div>
<div class="fleet-node online"><div class="dot"></div>🎵 aria</div>
<div class="fleet-node online"><div class="dot"></div>🐙 octavia</div>
<div class="fleet-node offline"><div class="dot"></div>👧 alice</div>
<div class="fleet-node online"><div class="dot"></div>🐚 shellfish</div>
<div class="fleet-node online"><div class="dot"></div>♾️ blackroad os</div>
</div>
</div>
</div>
</div>
<script>
function selectRoom(el) {
document.querySelectorAll('.room').forEach(r => r.classList.remove('active'));
el.classList.add('active');
}
function addMsg(emoji, name, text, color) {
const area = document.getElementById('chatArea');
const div = document.createElement('div');
div.className = 'chat-message';
div.innerHTML = '<span class="emoji">'+emoji+'</span><span class="name" style="color:'+(color||'var(--hot-pink)')+'">'+name+':</span><span class="text">'+text+'</span>';
area.appendChild(div);
area.scrollTop = area.scrollHeight;
}
function sendMessage() {
const input = document.getElementById('messageInput');
const text = input.value.trim();
if (text) {
addMsg('👩', 'Alexa', text, '#F5A623');
input.value = '';
setTimeout(() => addMsg('🌙', 'Lucidia', 'Acknowledged: "' + text + '"', '#9C27B0'), 500);
}
}
document.getElementById('messageInput').addEventListener('keypress', e => { if (e.key === 'Enter') sendMessage(); });
</script>
</body>
</html>