diff --git a/br95/app/globals.css b/br95/app/globals.css
new file mode 100644
index 0000000..195b0df
--- /dev/null
+++ b/br95/app/globals.css
@@ -0,0 +1,749 @@
+ :root {
+ /* Brand system */
+ --br-black: #02030a;
+ --br-bg-elevated: #050816;
+ --br-bg-alt: #090c1f;
+ --br-white: #ffffff;
+ --br-muted: #a7b0c7;
+ --br-border-subtle: rgba(255,255,255,0.08);
+ --br-accent-warm: #ff9a3c; /* top of logo gradient */
+ --br-accent-mid: #ff4fa3; /* magenta */
+ --br-accent-cool: #327cff; /* electric blue */
+ --br-accent-neo: #69f7ff; /* cyan */
+ --br-radius-lg: 24px;
+ --br-radius-md: 16px;
+ --br-radius-sm: 10px;
+ --br-shadow-soft: 0 18px 45px rgba(0,0,0,0.45);
+ --br-font-sans: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", sans-serif;
+ --br-font-mono: "JetBrains Mono", ui-monospace, Menlo, Monaco, Consolas, monospace;
+
+ /* BR‑95 chrome (retro-style, brand-colored) */
+ --br95-gray: #181c2a;
+ --br95-gray-light: #232842;
+ --br95-gray-lighter: #2f3554;
+ --br95-border-light: #4b5378;
+ --br95-border-dark: #050816;
+ --br95-border-darkest: #000000;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: var(--br-font-sans);
+ background: radial-gradient(circle at top, #121735 0, var(--br-black) 60%);
+ height: 100vh;
+ overflow: hidden;
+ color: var(--br-white);
+ -webkit-font-smoothing: antialiased;
+ }
+
+ /* CRT scanline overlay */
+ .scanline {
+ position: fixed;
+ inset: 0;
+ background: linear-gradient(to bottom, transparent 50%, rgba(255,255,255,0.06) 50%);
+ background-size: 100% 3px;
+ mix-blend-mode: soft-light;
+ opacity: 0.4;
+ pointer-events: none;
+ z-index: 9999;
+ }
+
+ /* Boot screen (from Desktop OS vibe) */
+ .boot-screen {
+ position: fixed;
+ inset: 0;
+ background: var(--br-black);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ z-index: 9000;
+ animation: bootFadeOut 0.6s ease 2.6s forwards;
+ }
+
+ @keyframes bootFadeOut {
+ to {
+ opacity: 0;
+ visibility: hidden;
+ }
+ }
+
+ .boot-logo-container {
+ text-align: center;
+ animation: bootIn 0.7s ease-out;
+ }
+
+ @keyframes bootIn {
+ from { opacity: 0; transform: translateY(16px); }
+ to { opacity: 1; transform: translateY(0); }
+ }
+
+ .boot-logo {
+ width: 180px;
+ height: 180px;
+ margin: 0 auto 28px;
+ background: conic-gradient(from 180deg,
+ var(--br-accent-warm),
+ var(--br-accent-mid),
+ var(--br-accent-cool),
+ var(--br-accent-warm));
+ border-radius: 38px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ box-shadow:
+ 0 0 60px rgba(255,154,60,0.35),
+ 0 0 100px rgba(255,79,163,0.28),
+ 0 20px 40px rgba(0,0,0,0.8);
+ animation: logoGlow 2s ease-in-out infinite;
+ }
+
+ @keyframes logoGlow {
+ 0%,100% {
+ box-shadow:
+ 0 0 60px rgba(255,154,60,0.35),
+ 0 0 100px rgba(255,79,163,0.28),
+ 0 20px 40px rgba(0,0,0,0.8);
+ }
+ 50% {
+ box-shadow:
+ 0 0 80px rgba(255,154,60,0.5),
+ 0 0 120px rgba(255,79,163,0.4),
+ 0 20px 40px rgba(0,0,0,0.9);
+ }
+ }
+
+ .boot-logo::before {
+ content: 'R';
+ font-size: 130px;
+ font-weight: 900;
+ color: var(--br-black);
+ font-family: var(--br-font-sans);
+ position: relative;
+ line-height: 1;
+ }
+
+ .boot-road {
+ position: absolute;
+ width: 34px;
+ height: 110px;
+ background: linear-gradient(to bottom,
+ transparent 0%,
+ rgba(255,255,255,0.98) 30%,
+ rgba(255,255,255,0.98) 70%,
+ transparent 100%);
+ border-radius: 17px;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%) rotate(-18deg);
+ opacity: 0.96;
+ }
+
+ .boot-title {
+ background: linear-gradient(120deg,
+ var(--br-accent-warm),
+ var(--br-accent-mid),
+ var(--br-accent-cool));
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+ font-size: 28px;
+ font-weight: 700;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ margin-bottom: 10px;
+ }
+
+ .boot-sub {
+ font-size: 12px;
+ color: var(--br-muted);
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ }
+
+ .boot-loading {
+ margin-top: 18px;
+ font-size: 11px;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ color: var(--br-muted);
+ }
+
+ .boot-loading::after {
+ content: '...';
+ animation: dots 1.2s infinite;
+ }
+
+ @keyframes dots {
+ 0%,20% { content: '.'; }
+ 40% { content: '..'; }
+ 60%,100% { content: '...'; }
+ }
+
+ /* Desktop shell */
+ .shell {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.4s ease;
+ }
+
+ .shell.ready {
+ opacity: 1;
+ pointer-events: auto;
+ }
+
+ /* Top menubar (from Desktop OS) */
+ .menubar {
+ background: linear-gradient(180deg, rgba(5,8,22,0.98) 0%, rgba(2,3,10,0.98) 100%);
+ backdrop-filter: blur(18px);
+ padding: 8px 16px;
+ display: flex;
+ align-items: center;
+ border-bottom: 1px solid var(--br-border-subtle);
+ box-shadow: 0 4px 24px rgba(0,0,0,0.5);
+ z-index: 50;
+ }
+
+ .menu-logo {
+ width: 28px;
+ height: 28px;
+ border-radius: 8px;
+ background: conic-gradient(from 180deg,
+ var(--br-accent-warm),
+ var(--br-accent-mid),
+ var(--br-accent-cool),
+ var(--br-accent-warm));
+ margin-right: 14px;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.7);
+ }
+
+ .menu-items {
+ display: flex;
+ gap: 6px;
+ flex: 1;
+ }
+
+ .menu-item {
+ padding: 4px 10px;
+ border-radius: 8px;
+ font-size: 12px;
+ color: var(--br-white);
+ cursor: pointer;
+ transition: background 0.14s ease, transform 0.14s ease;
+ }
+
+ .menu-item:hover {
+ background: rgba(255,255,255,0.05);
+ transform: translateY(-1px);
+ }
+
+ .system-info {
+ display: flex;
+ gap: 10px;
+ font-size: 11px;
+ color: var(--br-muted);
+ font-family: var(--br-font-mono);
+ }
+
+ .system-info span {
+ padding: 3px 8px;
+ border-radius: 6px;
+ border: 1px solid rgba(255,255,255,0.1);
+ background: rgba(255,255,255,0.03);
+ }
+
+ /* Desktop icons grid (retro layout) */
+ .desktop-area {
+ flex: 1;
+ padding: 20px;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, 90px);
+ grid-auto-rows: 95px;
+ gap: 22px;
+ align-content: start;
+ background-image:
+ linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
+ linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
+ background-size: 24px 24px;
+ position: relative;
+ overflow: auto;
+ }
+
+ .icon {
+ width: 86px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ cursor: pointer;
+ user-select: none;
+ transition: transform 0.15s ease;
+ }
+
+ .icon:hover {
+ transform: translateY(-3px);
+ }
+
+ .icon-image {
+ width: 64px;
+ height: 64px;
+ border-radius: var(--br-radius-md);
+ border: 1px solid var(--br-border-subtle);
+ background: linear-gradient(135deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 34px;
+ margin-bottom: 8px;
+ box-shadow: 0 4px 18px rgba(0,0,0,0.55);
+ position: relative;
+ backdrop-filter: blur(10px);
+ }
+
+ .icon-image::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ border-radius: var(--br-radius-md);
+ background: radial-gradient(circle at 18% 18%, rgba(255,255,255,0.18), transparent 60%);
+ pointer-events: none;
+ }
+
+ .icon-label {
+ text-align: center;
+ font-size: 12px;
+ font-weight: 500;
+ text-shadow: 0 2px 8px rgba(0,0,0,0.8);
+ }
+
+ /* BR‑95 window chrome (retro + brand) */
+ .window {
+ position: absolute;
+ background: var(--br95-gray);
+ border-radius: 10px;
+ border-top: 2px solid var(--br95-border-light);
+ border-left: 2px solid var(--br95-border-light);
+ border-right: 2px solid var(--br95-border-darkest);
+ border-bottom: 2px solid var(--br95-border-darkest);
+ box-shadow:
+ inset 1px 1px 0 var(--br95-gray-lighter),
+ 0 14px 40px rgba(0,0,0,0.7);
+ min-width: 420px;
+ min-height: 260px;
+ display: none;
+ z-index: 10;
+ overflow: hidden;
+ }
+
+ .window.active {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .window.maximized {
+ left: 0 !important;
+ top: 36px !important;
+ width: 100% !important;
+ height: calc(100vh - 36px - 40px) !important;
+ border-radius: 0;
+ z-index: 100;
+ }
+
+ .title-bar {
+ height: 26px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 3px 4px 3px 6px;
+ background: linear-gradient(90deg,
+ var(--br-accent-warm),
+ var(--br-accent-mid),
+ var(--br-accent-cool));
+ color: var(--br-white);
+ cursor: move;
+ user-select: none;
+ font-size: 12px;
+ font-weight: 600;
+ }
+
+ .title-text {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ text-shadow: 0 1px 2px rgba(0,0,0,0.6);
+ }
+
+ .title-buttons {
+ display: flex;
+ gap: 2px;
+ }
+
+ .title-button {
+ width: 18px;
+ height: 18px;
+ background: var(--br95-gray-light);
+ border-top: 1px solid var(--br95-border-light);
+ border-left: 1px solid var(--br95-border-light);
+ border-right: 1px solid var(--br95-border-darkest);
+ border-bottom: 1px solid var(--br95-border-darkest);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 11px;
+ font-weight: 700;
+ color: var(--br-black);
+ cursor: pointer;
+ box-shadow: inset 1px 1px 0 rgba(255,255,255,0.4);
+ }
+
+ .title-button:active {
+ border-top: 1px solid var(--br95-border-darkest);
+ border-left: 1px solid var(--br95-border-darkest);
+ border-right: 1px solid var(--br95-border-light);
+ border-bottom: 1px solid var(--br95-border-light);
+ box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4);
+ }
+
+ .window-inner {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ background: var(--br-bg-elevated);
+ padding: 10px;
+ color: var(--br-white);
+ font-size: 13px;
+ }
+
+ .content-header {
+ padding: 10px 12px;
+ border-radius: 8px;
+ background: linear-gradient(135deg,
+ rgba(255,154,60,0.08),
+ rgba(255,79,163,0.08),
+ rgba(50,124,255,0.08));
+ border: 1px solid rgba(255,255,255,0.06);
+ margin-bottom: 10px;
+ }
+
+ .content-header h2 {
+ font-size: 15px;
+ margin-bottom: 4px;
+ }
+
+ .content-header p {
+ font-size: 12px;
+ color: var(--br-muted);
+ }
+
+ .content-body {
+ flex: 1;
+ overflow: auto;
+ padding: 4px 2px 2px;
+ }
+
+ .grid {
+ display: grid;
+ gap: 10px;
+ }
+
+ .grid-2 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
+
+ .card {
+ background: rgba(4,10,32,0.98);
+ border-radius: 14px;
+ border: 1px solid var(--br-border-subtle);
+ padding: 10px 12px;
+ box-shadow: 0 8px 20px rgba(0,0,0,0.55);
+ }
+
+ .stat-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 12px;
+ padding: 4px 0;
+ border-bottom: 1px solid rgba(255,255,255,0.04);
+ }
+
+ .stat-row:last-child { border-bottom: none; }
+
+ .stat-label { color: var(--br-muted); }
+ .stat-value { font-family: var(--br-font-mono); }
+
+ .badge {
+ display: inline-flex;
+ align-items: center;
+ padding: 2px 8px;
+ border-radius: 999px;
+ font-size: 10px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ }
+
+ .badge-success {
+ background: rgba(34,197,94,0.16);
+ border: 1px solid rgba(34,197,94,0.5);
+ color: #22c55e;
+ }
+
+ .badge-info {
+ background: rgba(105,247,255,0.16);
+ border: 1px solid rgba(105,247,255,0.45);
+ color: var(--br-accent-neo);
+ }
+
+ .badge-warning {
+ background: rgba(251,191,36,0.16);
+ border: 1px solid rgba(251,191,36,0.45);
+ color: #fbbf24;
+ }
+
+ .btn-primary {
+ padding: 7px 16px;
+ border-radius: 999px;
+ border: none;
+ background: linear-gradient(135deg, var(--br-accent-warm), var(--br-accent-mid));
+ color: var(--br-black);
+ font-size: 12px;
+ font-weight: 600;
+ cursor: pointer;
+ box-shadow: 0 6px 16px rgba(0,0,0,0.7);
+ transition: transform 0.14s ease, box-shadow 0.14s ease, filter 0.14s ease;
+ }
+
+ .btn-primary:hover {
+ transform: translateY(-1px);
+ filter: brightness(1.05);
+ box-shadow: 0 10px 22px rgba(0,0,0,0.9);
+ }
+
+ .btn-primary:active {
+ transform: translateY(1px) scale(0.99);
+ box-shadow: 0 3px 10px rgba(0,0,0,0.8);
+ }
+
+ /* Terminal styling */
+ .terminal-screen {
+ background: var(--br-black);
+ color: var(--br-accent-neo);
+ font-family: var(--br-font-mono);
+ padding: 12px;
+ font-size: 12px;
+ height: 100%;
+ border-radius: 10px;
+ overflow-y: auto;
+ }
+
+ .terminal-line { margin-bottom: 4px; }
+
+ .terminal-prompt { color: var(--br-accent-mid); }
+
+ .terminal-cursor {
+ display: inline-block;
+ width: 8px;
+ height: 14px;
+ background: var(--br-accent-neo);
+ margin-left: 2px;
+ animation: blink 1s steps(1) infinite;
+ }
+
+ @keyframes blink {
+ 0%,49% { opacity: 1; }
+ 50%,100% { opacity: 0; }
+ }
+
+ /* Taskbar – BR‑95 style */
+ .taskbar {
+ height: 40px;
+ background: var(--br95-gray-light);
+ border-top: 2px solid var(--br95-border-light);
+ display: flex;
+ align-items: center;
+ padding: 4px;
+ gap: 4px;
+ box-shadow: 0 -6px 18px rgba(0,0,0,0.7);
+ z-index: 60;
+ }
+
+ .road-button {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 10px;
+ background: var(--br95-gray);
+ border-top: 2px solid var(--br95-border-light);
+ border-left: 2px solid var(--br95-border-light);
+ border-right: 2px solid var(--br95-border-darkest);
+ border-bottom: 2px solid var(--br95-border-darkest);
+ cursor: pointer;
+ font-size: 13px;
+ font-weight: 700;
+ color: var(--br-white);
+ box-shadow: inset 1px 1px 0 rgba(255,255,255,0.4);
+ }
+
+ .road-logo {
+ width: 22px;
+ height: 22px;
+ border-radius: 4px;
+ background: conic-gradient(from 180deg,
+ var(--br-accent-warm),
+ var(--br-accent-mid),
+ var(--br-accent-cool),
+ var(--br-accent-warm));
+ display: inline-block;
+ }
+
+ .taskbar-apps {
+ flex: 1;
+ display: flex;
+ gap: 4px;
+ padding: 0 6px;
+ overflow-x: auto;
+ }
+
+ .taskbar-app {
+ min-width: 120px;
+ max-width: 160px;
+ height: 30px;
+ background: var(--br95-gray);
+ border-top: 2px solid var(--br95-border-light);
+ border-left: 2px solid var(--br95-border-light);
+ border-right: 2px solid var(--br95-border-darkest);
+ border-bottom: 2px solid var(--br95-border-darkest);
+ padding: 0 8px;
+ display: flex;
+ align-items: center;
+ font-size: 12px;
+ color: var(--br-white);
+ cursor: pointer;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ box-shadow: inset 1px 1px 0 rgba(255,255,255,0.25);
+ }
+
+ .taskbar-app.active-app {
+ border-top: 2px solid var(--br95-border-darkest);
+ border-left: 2px solid var(--br95-border-darkest);
+ border-right: 2px solid var(--br95-border-light);
+ border-bottom: 2px solid var(--br95-border-light);
+ box-shadow: inset 1px 1px 2px rgba(0,0,0,0.5);
+ background: var(--br95-gray-lighter);
+ }
+
+ .system-tray {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 0 6px;
+ color: var(--br-white);
+ font-size: 14px;
+ }
+
+ .clock {
+ min-width: 80px;
+ padding: 3px 8px;
+ border-top: 2px solid var(--br95-border-darkest);
+ border-left: 2px solid var(--br95-border-darkest);
+ border-right: 2px solid var(--br95-border-light);
+ border-bottom: 2px solid var(--br95-border-light);
+ font-size: 12px;
+ text-align: center;
+ background: var(--br95-gray);
+ font-family: var(--br-font-mono);
+ }
+
+ /* Road menu (Start menu but BlackRoad) */
+ .road-menu {
+ position: fixed;
+ left: 4px;
+ bottom: 44px;
+ width: 280px;
+ background: rgba(4,10,32,0.98);
+ border-radius: 12px;
+ border: 1px solid rgba(255,255,255,0.18);
+ box-shadow: 0 18px 50px rgba(0,0,0,0.85);
+ display: none;
+ flex-direction: column;
+ overflow: hidden;
+ z-index: 80;
+ }
+
+ .road-menu.active { display: flex; }
+
+ .road-menu-header {
+ padding: 14px;
+ background: linear-gradient(135deg,
+ rgba(255,154,60,0.2),
+ rgba(255,79,163,0.18),
+ rgba(50,124,255,0.18));
+ border-bottom: 1px solid rgba(255,255,255,0.18);
+ }
+
+ .road-menu-header h3 {
+ font-size: 15px;
+ margin-bottom: 4px;
+ }
+
+ .road-menu-header p {
+ font-size: 11px;
+ color: var(--br-muted);
+ }
+
+ .road-menu-content {
+ padding: 6px;
+ max-height: 60vh;
+ overflow-y: auto;
+ background: rgba(2,5,18,0.96);
+ }
+
+ .road-menu-item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 6px 8px;
+ border-radius: 8px;
+ font-size: 12px;
+ cursor: pointer;
+ color: var(--br-muted);
+ transition: background 0.12s ease, color 0.12s ease;
+ }
+
+ .road-menu-item span.emoji { font-size: 18px; }
+
+ .road-menu-item:hover {
+ background: rgba(255,255,255,0.07);
+ color: var(--br-white);
+ }
+
+ .road-menu-separator {
+ height: 1px;
+ margin: 4px 4px;
+ background: rgba(255,255,255,0.12);
+ }
+
+ /* Scrollbars */
+ ::-webkit-scrollbar { width: 12px; height: 12px; }
+ ::-webkit-scrollbar-track {
+ background: var(--br95-gray);
+ border-left: 1px solid var(--br95-border-darkest);
+ }
+ ::-webkit-scrollbar-thumb {
+ background: var(--br95-gray-light);
+ border-top: 2px solid var(--br95-border-light);
+ border-left: 2px solid var(--br95-border-light);
+ border-right: 2px solid var(--br95-border-darkest);
+ border-bottom: 2px solid var(--br95-border-darkest);
+ }
+
\ No newline at end of file
diff --git a/br95/app/layout.tsx b/br95/app/layout.tsx
new file mode 100644
index 0000000..47f42ab
--- /dev/null
+++ b/br95/app/layout.tsx
@@ -0,0 +1,15 @@
+import type { Metadata } from 'next';
+import './globals.css';
+
+export const metadata: Metadata = {
+ title: 'BlackRoad OS – BR‑95 Edition',
+ description: 'BlackRoad OS retro desktop rebuilt as modern Next.js components.',
+};
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
{children}
+
+ );
+}
diff --git a/br95/app/page.tsx b/br95/app/page.tsx
new file mode 100644
index 0000000..96f0604
--- /dev/null
+++ b/br95/app/page.tsx
@@ -0,0 +1,7 @@
+'use client';
+
+import DesktopLayout from '../components/DesktopLayout';
+
+export default function HomePage() {
+ return ;
+}
diff --git a/br95/components/DesktopLayout.tsx b/br95/components/DesktopLayout.tsx
new file mode 100644
index 0000000..58d0d3e
--- /dev/null
+++ b/br95/components/DesktopLayout.tsx
@@ -0,0 +1,200 @@
+import React from 'react';
+import AgentsWindow from './windows/AgentsWindow';
+import BlackstreamWindow from './windows/BlackstreamWindow';
+import LucidiaWindow from './windows/LucidiaWindow';
+import MinerWindow from './windows/MinerWindow';
+import PiWindow from './windows/PiWindow';
+import RoadchainWindow from './windows/RoadchainWindow';
+import RoadcraftWindow from './windows/RoadcraftWindow';
+import RoadmailWindow from './windows/RoadmailWindow';
+import RoadviewWindow from './windows/RoadviewWindow';
+import SocialWindow from './windows/SocialWindow';
+import TerminalWindow from './windows/TerminalWindow';
+import WalletWindow from './windows/WalletWindow';
+import BootScreen from './shared/BootScreen';
+import Taskbar from './shared/Taskbar';
+import RoadMenu from './shared/RoadMenu';
+import { useWindowManager, WindowId } from '../hooks/useWindowManager';
+
+const desktopIcons: { id: WindowId; icon: string; label: string }[] = [
+ { id: 'lucidia', icon: '🧠', label: 'Lucidia Core' },
+ { id: 'agents', icon: '🤖', label: 'AI Agents' },
+ { id: 'roadchain', icon: '⛓️', label: 'RoadChain' },
+ { id: 'wallet', icon: '💰', label: 'Wallet' },
+ { id: 'terminal', icon: '💻', label: 'Terminal' },
+ { id: 'roadmail', icon: '📧', label: 'RoadMail' },
+ { id: 'social', icon: '👥', label: 'Social' },
+ { id: 'blackstream', icon: '📺', label: 'BlackStream' },
+ { id: 'roadview', icon: '🌍', label: 'RoadView' },
+ { id: 'pi', icon: '🥧', label: 'Pi Network' },
+ { id: 'miner', icon: '⛏️', label: 'Miner' },
+ { id: 'roadcraft', icon: '⛏️', label: 'RoadCraft' },
+];
+
+export default function DesktopLayout() {
+ const {
+ windowStates,
+ openWindows,
+ activeWindow,
+ roadMenuOpen,
+ shellReady,
+ clockText,
+ lucidiaStats,
+ roadchainStats,
+ walletStats,
+ minerStats,
+ menuRef,
+ menuButtonRef,
+ openWindow,
+ closeWindow,
+ minimizeWindow,
+ maximizeWindow,
+ startDrag,
+ focusWindow,
+ toggleRoadMenu,
+ taskbarToggle,
+ } = useWindowManager();
+
+ return (
+ <>
+
+
+
+
+
+
+
File
+
View
+
Agents
+
RoadChain
+
+
+ BlackRoad OS v1.0
+ Agents: 1000
+
+
+
+
+ {desktopIcons.map((item) => (
+
openWindow(item.id)}>
+
{item.icon}
+
{item.label}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
taskbarToggle(id)}
+ onToggleMenu={toggleRoadMenu}
+ menuButtonRef={menuButtonRef}
+ />
+
+ openWindow(id)} menuRef={menuRef} />
+
+ >
+ );
+}
diff --git a/br95/components/shared/BootScreen.tsx b/br95/components/shared/BootScreen.tsx
new file mode 100644
index 0000000..fedaad2
--- /dev/null
+++ b/br95/components/shared/BootScreen.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+
+type Props = {
+ bootActive: boolean;
+};
+
+export default function BootScreen({ bootActive }: Props) {
+ return (
+
+
+
+
BlackRoad OS
+
BR‑95 Edition · Safe Passage Through The Chaos
+
System Loading
+
+
+ );
+}
diff --git a/br95/components/shared/RoadMenu.tsx b/br95/components/shared/RoadMenu.tsx
new file mode 100644
index 0000000..12d1a30
--- /dev/null
+++ b/br95/components/shared/RoadMenu.tsx
@@ -0,0 +1,42 @@
+import React from 'react';
+import { WindowId } from '../../hooks/useWindowManager';
+
+type Props = {
+ isOpen: boolean;
+ onOpenWindow: (id: WindowId) => void;
+ menuRef: React.RefObject;
+};
+
+const items: { id: WindowId; icon: string; label: string }[] = [
+ { id: 'lucidia', icon: '🧠', label: 'Lucidia Core' },
+ { id: 'agents', icon: '🤖', label: 'AI Agents' },
+ { id: 'roadchain', icon: '⛓️', label: 'RoadChain Explorer' },
+ { id: 'wallet', icon: '💰', label: 'RoadCoin Wallet' },
+ { id: 'roadmail', icon: '📧', label: 'RoadMail' },
+ { id: 'terminal', icon: '💻', label: 'Terminal' },
+ { id: 'pi', icon: '🥧', label: 'Pi Network' },
+ { id: 'miner', icon: '⛏️', label: 'RoadCoin Miner' },
+ { id: 'roadcraft', icon: '⛏️', label: 'RoadCraft' },
+];
+
+export default function RoadMenu({ isOpen, onOpenWindow, menuRef }: Props) {
+ return (
+
+ );
+}
diff --git a/br95/components/shared/Taskbar.tsx b/br95/components/shared/Taskbar.tsx
new file mode 100644
index 0000000..da960c3
--- /dev/null
+++ b/br95/components/shared/Taskbar.tsx
@@ -0,0 +1,63 @@
+import React from 'react';
+import { WindowId } from '../../hooks/useWindowManager';
+
+type Props = {
+ openWindows: WindowId[];
+ activeWindow: WindowId | null;
+ clockText: string;
+ onTaskbarClick: (id: WindowId) => void;
+ onToggleMenu: () => void;
+ menuButtonRef: React.RefObject;
+};
+
+const titles: Record = {
+ lucidia: '🧠 Lucidia',
+ agents: '🤖 Agents',
+ roadchain: '⛓️ Chain',
+ wallet: '💰 Wallet',
+ roadmail: '📧 Mail',
+ social: '👥 Social',
+ blackstream: '📺 Stream',
+ roadview: '🌍 RoadView',
+ terminal: '💻 Terminal',
+ pi: '🥧 Pi',
+ miner: '⛏️ Miner',
+ roadcraft: '⛏️ RoadCraft',
+};
+
+export default function Taskbar({
+ openWindows,
+ activeWindow,
+ clockText,
+ onTaskbarClick,
+ onToggleMenu,
+ menuButtonRef,
+}: Props) {
+ return (
+
+
+
+ Road
+
+
+ {openWindows.map((id) => (
+
onTaskbarClick(id)}
+ >
+ {titles[id] ?? id}
+
+ ))}
+
+
+ 🌐
+ 🔊
+ ⛓️
+
+
+ {clockText}
+
+
+ );
+}
diff --git a/br95/components/shared/WindowFrame.tsx b/br95/components/shared/WindowFrame.tsx
new file mode 100644
index 0000000..751714b
--- /dev/null
+++ b/br95/components/shared/WindowFrame.tsx
@@ -0,0 +1,67 @@
+import React from 'react';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ id: string;
+ title: string;
+ icon: string;
+ state: WindowState;
+ children: React.ReactNode;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function WindowFrame({
+ id,
+ title,
+ icon,
+ state,
+ children,
+ onClose,
+ onMinimize,
+ onMaximize,
+ onDragStart,
+ onFocus,
+}: Props) {
+ if (!state) return null;
+
+ const style = state.isMaximized
+ ? { zIndex: state.zIndex }
+ : {
+ left: state.position.x,
+ top: state.position.y,
+ width: state.size.width,
+ height: state.size.height,
+ zIndex: state.zIndex,
+ };
+
+ return (
+ onFocus(id)}
+ >
+
onDragStart(id, e)}>
+
+ {icon}
+ {title}
+
+
+
onMinimize(id)}>
+ _
+
+
onMaximize(id)}>
+ □
+
+
onClose(id)}>
+ ×
+
+
+
+ {children}
+
+ );
+}
diff --git a/br95/components/windows/AgentsWindow.tsx b/br95/components/windows/AgentsWindow.tsx
new file mode 100644
index 0000000..699b702
--- /dev/null
+++ b/br95/components/windows/AgentsWindow.tsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function AgentsWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
1,000 Unique Agents
+
Each with names, memories, families & Unity homes
+
+
+
+
+
🤖
+
ID Agent‑042
+
Persona Alice
+
Status Active
+
Tasks Today 247
+
+
+
🤖
+
ID Agent‑189
+
Persona Marcus
+
Status Active
+
Tasks Today 189
+
+
+
+ View All 1000 Agents
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/BlackstreamWindow.tsx b/br95/components/windows/BlackstreamWindow.tsx
new file mode 100644
index 0000000..ad9b5c4
--- /dev/null
+++ b/br95/components/windows/BlackstreamWindow.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function BlackstreamWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
Trending Streams
+
OS demos, agent orchestration runs, and live RoadChain dashboards
+
+
+
+ Embedded stream player coming soon.
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/LucidiaWindow.tsx b/br95/components/windows/LucidiaWindow.tsx
new file mode 100644
index 0000000..6eb6ba4
--- /dev/null
+++ b/br95/components/windows/LucidiaWindow.tsx
@@ -0,0 +1,79 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { LucidiaStats, WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ stats: LucidiaStats;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function LucidiaWindow({ state, stats, ...handlers }: Props) {
+ return (
+
+
+
+
Recursive AI Engine
+
Trinary logic · Paraconsistent reasoning · PS‑SHA∞ memory
+
+
+
+
+
+ Active Agents
+ {stats.activeAgents} / {stats.totalAgents}
+
+
+ Memory Journals
+ {stats.memoryJournals} streams
+
+
+ Event Bus
+ {stats.eventBusRate} events/sec
+
+
+ Uptime
+ {stats.uptime.toFixed(2)}%
+
+
+
+
+ Mode
+ Trinary (1/0/‑1)
+
+
+ Contradictions
+ Paraconsistent
+
+
+ Memory Hash
+ PS‑SHA∞
+
+
+ Coordination
+ Hybrid P2P
+
+
+
+
+
+
+ Agent‑042 proposed new routing rule • 2m ago
+
+
+ Agent‑189 memory journal sync complete • 5m ago
+
+
+ Agent‑734 contradiction quarantined • 12m ago
+
+
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/MinerWindow.tsx b/br95/components/windows/MinerWindow.tsx
new file mode 100644
index 0000000..31502b8
--- /dev/null
+++ b/br95/components/windows/MinerWindow.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { MinerStats, WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ stats: MinerStats;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function MinerWindow({ state, stats, ...handlers }: Props) {
+ return (
+
+
+
+
Mining Active
+
Contributing work to RoadChain network
+
+
+
+
Hashrate {stats.hashRate}
+
Accepted Shares {stats.sharesAccepted.toLocaleString()}
+
Pool {stats.poolName}
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/PiWindow.tsx b/br95/components/windows/PiWindow.tsx
new file mode 100644
index 0000000..2ddd5e4
--- /dev/null
+++ b/br95/components/windows/PiWindow.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function PiWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
Connected Devices
+
4 devices online · 1 Jetson Orin Nano
+
+
+
+
Jetson Orin Nano Online
+
Lucidia‑Pi‑01 Online
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/RoadchainWindow.tsx b/br95/components/windows/RoadchainWindow.tsx
new file mode 100644
index 0000000..0d3a4f5
--- /dev/null
+++ b/br95/components/windows/RoadchainWindow.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { RoadChainStats, WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ stats: RoadChainStats;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function RoadchainWindow({ state, stats, ...handlers }: Props) {
+ return (
+
+
+
+
RoadChain Network
+
Transparent AI governance on a distributed ledger
+
+
+
+
+
Block Height {stats.currentBlock.toLocaleString()}
+
Network Hash {stats.networkHashrate}
+
Active Nodes {stats.activeNodes.toLocaleString()}
+
+
+
Your Hashrate {stats.yourHashrate}
+
Shares {stats.shares}
+
Daily Earnings {stats.dailyEarnings}
+
+
+
+
+
+ Block #1,247,891 • 23s ago
+ Hash: 0x8f4a2...c7b9d • 247 tx
+
+
+ Block #1,247,890 • 2m ago
+ Hash: 0x3c9e1...f2a4b • 189 tx
+
+
+ Block #1,247,889 • 4m ago
+ Hash: 0x7d2b3...e8c1f • 312 tx
+
+
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/RoadcraftWindow.tsx b/br95/components/windows/RoadcraftWindow.tsx
new file mode 100644
index 0000000..ecb502b
--- /dev/null
+++ b/br95/components/windows/RoadcraftWindow.tsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function RoadcraftWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
Voxel World Builder
+
Design agent habitats & quantum sandboxes
+
+
+ New World
+
+
+
+ );
+}
diff --git a/br95/components/windows/RoadmailWindow.tsx b/br95/components/windows/RoadmailWindow.tsx
new file mode 100644
index 0000000..f7e7c33
--- /dev/null
+++ b/br95/components/windows/RoadmailWindow.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function RoadmailWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
Inbox
+
Secure AI‑aware communication
+
+
+
+
Welcome to BlackRoad OS
+
From: BlackRoad Team • Today
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/RoadviewWindow.tsx b/br95/components/windows/RoadviewWindow.tsx
new file mode 100644
index 0000000..a384649
--- /dev/null
+++ b/br95/components/windows/RoadviewWindow.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function RoadviewWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
Welcome to BlackRoad
+
The complete AI orchestration ecosystem, in one desktop.
+
+
+
+
+ This browser surface will eventually connect to your real BlackRoad services:
+ core.blackroad.systems, api.blackroad.systems,
+ agents.blackroad.systems, and more.
+
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/SocialWindow.tsx b/br95/components/windows/SocialWindow.tsx
new file mode 100644
index 0000000..a48b151
--- /dev/null
+++ b/br95/components/windows/SocialWindow.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function SocialWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
Your Feed
+
Operators, agents, and ledgers talking in real time
+
+
+
+
+ Prism Console · New deployment shipped to RoadChain.
+ 2 minutes ago
+
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/TerminalWindow.tsx b/br95/components/windows/TerminalWindow.tsx
new file mode 100644
index 0000000..7710131
--- /dev/null
+++ b/br95/components/windows/TerminalWindow.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function TerminalWindow({ state, ...handlers }: Props) {
+ return (
+
+
+
+
BlackRoad OS Terminal v2.4.1
+
Copyright (c) 2024 BlackRoad Inc.
+
────────────────────────────────────────────────────
+
+ blackroad@cecilia:~$ lucidia status
+
+
✓ Lucidia Core: OPERATIONAL
+
✓ Active Agents: 1000/1000
+
✓ Memory Journals: 1000 active streams
+
✓ Event Bus: 847 events/sec
+
✓ System Health: 99.95%
+
+ blackroad@cecilia:~$ roadchain sync
+
+
Syncing with RoadChain network...
+
✓ Block height: 1,247,891
+
✓ Peers: 2847 connected
+
+ blackroad@cecilia:~$
+
+
+
+
+
+ );
+}
diff --git a/br95/components/windows/WalletWindow.tsx b/br95/components/windows/WalletWindow.tsx
new file mode 100644
index 0000000..f86da0a
--- /dev/null
+++ b/br95/components/windows/WalletWindow.tsx
@@ -0,0 +1,52 @@
+import React from 'react';
+import WindowFrame from '../shared/WindowFrame';
+import { WalletStats, WindowState } from '../../hooks/useWindowManager';
+
+type Props = {
+ state: WindowState;
+ stats: WalletStats;
+ onClose: (id: string) => void;
+ onMinimize: (id: string) => void;
+ onMaximize: (id: string) => void;
+ onDragStart: (id: string, event: React.MouseEvent) => void;
+ onFocus: (id: string) => void;
+};
+
+export default function WalletWindow({ state, stats, ...handlers }: Props) {
+ return (
+
+
+
+
{stats.balanceRC.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} RC
+
≈ ${stats.balanceUSD.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} USD • Synced with RoadChain
+
+
+
+ 📤 Send
+
+ 📥 Receive
+
+
+
+
+
+
Received
+
Mining rewards • 2h ago
+
+
+47.23 RC
+
+
+
+
+
+
Sent
+
Payment to Alice • Yesterday
+
+
‑12.50 RC
+
+
+
+
+
+ );
+}
diff --git a/br95/hooks/useWindowManager.ts b/br95/hooks/useWindowManager.ts
new file mode 100644
index 0000000..f625dbc
--- /dev/null
+++ b/br95/hooks/useWindowManager.ts
@@ -0,0 +1,412 @@
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+
+export type WindowState = {
+ id: string;
+ position: { x: number; y: number };
+ size: { width: number; height: number };
+ isOpen: boolean;
+ isMaximized: boolean;
+ zIndex: number;
+};
+
+export type LucidiaStats = {
+ status: string;
+ activeAgents: number;
+ totalAgents: number;
+ memoryJournals: number;
+ eventBusRate: number;
+ uptime: number;
+};
+
+export type RoadChainStats = {
+ currentBlock: number;
+ networkHashrate: string;
+ activeNodes: number;
+ yourHashrate: string;
+ shares: string;
+ dailyEarnings: string;
+};
+
+export type WalletStats = {
+ balanceRC: number;
+ balanceUSD: number;
+};
+
+export type MinerStats = {
+ hashRate: string;
+ sharesAccepted: number;
+ poolName: string;
+};
+
+export type WindowId =
+ | 'lucidia'
+ | 'agents'
+ | 'roadchain'
+ | 'wallet'
+ | 'terminal'
+ | 'roadmail'
+ | 'social'
+ | 'blackstream'
+ | 'roadview'
+ | 'pi'
+ | 'miner'
+ | 'roadcraft';
+
+const API_BASE = '/api/br95';
+
+const WINDOW_PRESETS: Record = {
+ lucidia: { id: 'lucidia', position: { x: 60, y: 90 }, size: { width: 680, height: 420 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ agents: { id: 'agents', position: { x: 120, y: 120 }, size: { width: 760, height: 460 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ roadchain: { id: 'roadchain', position: { x: 180, y: 80 }, size: { width: 760, height: 440 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ wallet: { id: 'wallet', position: { x: 220, y: 130 }, size: { width: 520, height: 380 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ terminal: { id: 'terminal', position: { x: 140, y: 180 }, size: { width: 720, height: 420 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ roadmail: { id: 'roadmail', position: { x: 80, y: 80 }, size: { width: 640, height: 380 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ social: { id: 'social', position: { x: 160, y: 90 }, size: { width: 640, height: 380 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ blackstream: { id: 'blackstream', position: { x: 200, y: 100 }, size: { width: 720, height: 420 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ roadview: { id: 'roadview', position: { x: 120, y: 70 }, size: { width: 820, height: 460 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ pi: { id: 'pi', position: { x: 220, y: 140 }, size: { width: 540, height: 320 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ miner: { id: 'miner', position: { x: 260, y: 120 }, size: { width: 560, height: 320 }, isOpen: false, isMaximized: false, zIndex: 10 },
+ roadcraft: { id: 'roadcraft', position: { x: 300, y: 160 }, size: { width: 600, height: 360 }, isOpen: false, isMaximized: false, zIndex: 10 },
+};
+
+export function useWindowManager() {
+ const [windowStates, setWindowStates] = useState>(WINDOW_PRESETS);
+ const [openWindows, setOpenWindows] = useState([]);
+ const [activeWindow, setActiveWindow] = useState(null);
+ const [roadMenuOpen, setRoadMenuOpen] = useState(false);
+ const [shellReady, setShellReady] = useState(false);
+ const [clock, setClock] = useState(() => new Date());
+ const zIndexRef = useRef(10);
+ const dragRef = useRef<{ id: WindowId; offsetX: number; offsetY: number } | null>(null);
+ const menuRef = useRef(null);
+ const menuButtonRef = useRef(null);
+ const wsRef = useRef(null);
+ const reconnectRef = useRef(null);
+
+ const [lucidiaStats, setLucidiaStats] = useState({
+ status: 'OPERATIONAL',
+ activeAgents: 1000,
+ totalAgents: 1000,
+ memoryJournals: 1000,
+ eventBusRate: 847,
+ uptime: 99.95,
+ });
+
+ const [roadchainStats, setRoadchainStats] = useState({
+ currentBlock: 1247891,
+ networkHashrate: '847.3 TH/s',
+ activeNodes: 2847,
+ yourHashrate: '1.2 GH/s',
+ shares: '8,423 accepted',
+ dailyEarnings: '47.23 RC',
+ });
+
+ const [walletStats, setWalletStats] = useState({
+ balanceRC: 1247.89,
+ balanceUSD: 18705,
+ });
+
+ const [minerStats, setMinerStats] = useState({
+ hashRate: '1.2 GH/s',
+ sharesAccepted: 8423,
+ poolName: 'BR‑Global‑01',
+ });
+
+ useEffect(() => {
+ const timer = setTimeout(() => setShellReady(true), 2400);
+ return () => clearTimeout(timer);
+ }, []);
+
+ useEffect(() => {
+ const interval = setInterval(() => setClock(new Date()), 1000);
+ return () => clearInterval(interval);
+ }, []);
+
+ useEffect(() => {
+ const handleClick = (event: MouseEvent) => {
+ if (!roadMenuOpen) return;
+ const target = event.target as Node;
+ if (menuRef.current?.contains(target) || menuButtonRef.current?.contains(target)) {
+ return;
+ }
+ setRoadMenuOpen(false);
+ };
+
+ document.addEventListener('click', handleClick);
+ return () => document.removeEventListener('click', handleClick);
+ }, [roadMenuOpen]);
+
+ const focusWindow = useCallback((id: WindowId) => {
+ setWindowStates((prev) => {
+ const current = prev[id];
+ if (!current) return prev;
+ const nextZ = ++zIndexRef.current;
+ return { ...prev, [id]: { ...current, zIndex: nextZ } };
+ });
+ setActiveWindow(id);
+ }, []);
+
+ const openWindow = useCallback((id: WindowId) => {
+ setWindowStates((prev) => {
+ const current = prev[id];
+ if (!current) return prev;
+ const nextZ = ++zIndexRef.current;
+ return { ...prev, [id]: { ...current, isOpen: true, zIndex: nextZ } };
+ });
+ setActiveWindow(id);
+ setOpenWindows((prev) => (prev.includes(id) ? prev : [...prev, id]));
+ setRoadMenuOpen(false);
+ }, []);
+
+ const closeWindow = useCallback((id: WindowId) => {
+ setWindowStates((prev) => {
+ const current = prev[id];
+ if (!current) return prev;
+ return { ...prev, [id]: { ...current, isOpen: false } };
+ });
+ setOpenWindows((prev) => prev.filter((win) => win !== id));
+ setActiveWindow((prev) => (prev === id ? null : prev));
+ }, []);
+
+ const minimizeWindow = useCallback((id: WindowId) => {
+ setWindowStates((prev) => {
+ const current = prev[id];
+ if (!current) return prev;
+ return { ...prev, [id]: { ...current, isOpen: false } };
+ });
+ setActiveWindow((prev) => (prev === id ? null : prev));
+ }, []);
+
+ const maximizeWindow = useCallback((id: WindowId) => {
+ setWindowStates((prev) => {
+ const current = prev[id];
+ if (!current) return prev;
+ const nextZ = ++zIndexRef.current;
+ return { ...prev, [id]: { ...current, isMaximized: !current.isMaximized, zIndex: nextZ } };
+ });
+ setActiveWindow(id);
+ }, []);
+
+ const startDrag = useCallback((id: WindowId, event: React.MouseEvent) => {
+ event.preventDefault();
+ setWindowStates((prev) => {
+ const current = prev[id];
+ if (!current || current.isMaximized) return prev;
+ dragRef.current = {
+ id,
+ offsetX: event.clientX - current.position.x,
+ offsetY: event.clientY - current.position.y,
+ };
+ const nextZ = ++zIndexRef.current;
+ return { ...prev, [id]: { ...current, zIndex: nextZ } };
+ });
+ setActiveWindow(id);
+ }, []);
+
+ useEffect(() => {
+ const handleMove = (event: MouseEvent) => {
+ if (!dragRef.current) return;
+ setWindowStates((prev) => {
+ const current = prev[dragRef.current!.id];
+ if (!current || current.isMaximized) return prev;
+ const nextPosition = {
+ x: event.clientX - dragRef.current!.offsetX,
+ y: event.clientY - dragRef.current!.offsetY,
+ };
+ return { ...prev, [current.id]: { ...current, position: nextPosition } };
+ });
+ };
+
+ const handleUp = () => {
+ dragRef.current = null;
+ };
+
+ window.addEventListener('mousemove', handleMove);
+ window.addEventListener('mouseup', handleUp);
+ return () => {
+ window.removeEventListener('mousemove', handleMove);
+ window.removeEventListener('mouseup', handleUp);
+ };
+ }, []);
+
+ const toggleRoadMenu = useCallback(() => {
+ setRoadMenuOpen((prev) => !prev);
+ }, []);
+
+ const taskbarToggle = useCallback(
+ (id: WindowId) => {
+ if (windowStates[id]?.isOpen && activeWindow === id) {
+ minimizeWindow(id);
+ } else {
+ openWindow(id);
+ }
+ },
+ [activeWindow, minimizeWindow, openWindow, windowStates],
+ );
+
+ const clockText = useMemo(() => clock.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }), [clock]);
+
+ const fetchLucidia = useCallback(async () => {
+ try {
+ const response = await fetch(`${API_BASE}/lucidia`);
+ const data = await response.json();
+ setLucidiaStats((prev) => ({
+ status: data.status ? String(data.status).toUpperCase() : prev.status,
+ activeAgents: data.active_agents ?? prev.activeAgents,
+ totalAgents: data.total_agents ?? prev.totalAgents,
+ memoryJournals: data.memory_journals ?? prev.memoryJournals,
+ eventBusRate: data.event_bus_rate ?? prev.eventBusRate,
+ uptime: data.system_health ?? prev.uptime,
+ }));
+ } catch (error) {
+ console.error('Failed to fetch Lucidia stats:', error);
+ }
+ }, []);
+
+ const fetchRoadchain = useCallback(async () => {
+ try {
+ const response = await fetch(`${API_BASE}/roadchain`);
+ const data = await response.json();
+ setRoadchainStats((prev) => ({
+ currentBlock: data.current_block ?? prev.currentBlock,
+ networkHashrate: data.network_hashrate ?? prev.networkHashrate,
+ activeNodes: data.active_nodes ?? prev.activeNodes,
+ yourHashrate: data.network_hashrate ?? prev.yourHashrate,
+ shares: prev.shares,
+ dailyEarnings: prev.dailyEarnings,
+ }));
+ } catch (error) {
+ console.error('Failed to fetch RoadChain stats:', error);
+ }
+ }, []);
+
+ const fetchWallet = useCallback(async () => {
+ try {
+ const response = await fetch(`${API_BASE}/wallet`);
+ const data = await response.json();
+ setWalletStats((prev) => ({
+ balanceRC: data.balance_rc ?? prev.balanceRC,
+ balanceUSD: data.balance_usd ?? prev.balanceUSD,
+ }));
+ } catch (error) {
+ console.error('Failed to fetch Wallet stats:', error);
+ }
+ }, []);
+
+ const fetchMiner = useCallback(async () => {
+ try {
+ const response = await fetch(`${API_BASE}/miner`);
+ const data = await response.json();
+ setMinerStats((prev) => ({
+ hashRate: data.hash_rate ?? prev.hashRate,
+ sharesAccepted: data.shares_accepted ?? prev.sharesAccepted,
+ poolName: data.pool_name ?? prev.poolName,
+ }));
+ } catch (error) {
+ console.error('Failed to fetch Miner stats:', error);
+ }
+ }, []);
+
+ const connectWebSocket = useCallback(() => {
+ if (typeof window === 'undefined') return;
+ const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
+ const wsUrl = `${protocol}//${window.location.host}${API_BASE}/ws`;
+
+ const socket = new WebSocket(wsUrl);
+ wsRef.current = socket;
+
+ socket.onmessage = (event) => {
+ try {
+ const message = JSON.parse(event.data);
+ switch (message.type) {
+ case 'miner_update':
+ setMinerStats((prev) => ({
+ ...prev,
+ hashRate: message.data?.hash_rate ?? prev.hashRate,
+ sharesAccepted: message.data?.shares_accepted ?? prev.sharesAccepted,
+ }));
+ break;
+ case 'roadchain_update':
+ setRoadchainStats((prev) => ({
+ ...prev,
+ currentBlock: message.data?.current_block ?? prev.currentBlock,
+ activeNodes: message.data?.active_nodes ?? prev.activeNodes,
+ }));
+ break;
+ case 'wallet_update':
+ setWalletStats((prev) => ({
+ ...prev,
+ balanceRC: message.data?.balance_rc ?? prev.balanceRC,
+ balanceUSD: message.data?.balance_usd ?? prev.balanceUSD,
+ }));
+ break;
+ default:
+ break;
+ }
+ } catch (error) {
+ console.error('Failed to parse WebSocket message:', error);
+ }
+ };
+
+ socket.onclose = () => {
+ if (reconnectRef.current) {
+ clearTimeout(reconnectRef.current);
+ }
+ reconnectRef.current = setTimeout(connectWebSocket, 5000);
+ };
+
+ socket.onerror = (error) => {
+ console.error('WebSocket error:', error);
+ };
+ }, []);
+
+ useEffect(() => {
+ if (!shellReady) return;
+
+ let lucidiaInterval: NodeJS.Timeout | null = null;
+ const startApis = () => {
+ fetchLucidia();
+ fetchRoadchain();
+ fetchWallet();
+ fetchMiner();
+ connectWebSocket();
+ lucidiaInterval = setInterval(fetchLucidia, 30000);
+ };
+
+ const timer = setTimeout(startApis, 3000);
+
+ return () => {
+ clearTimeout(timer);
+ if (lucidiaInterval) {
+ clearInterval(lucidiaInterval);
+ }
+ if (reconnectRef.current) {
+ clearTimeout(reconnectRef.current);
+ }
+ wsRef.current?.close();
+ };
+ }, [connectWebSocket, fetchLucidia, fetchMiner, fetchRoadchain, fetchWallet, shellReady]);
+
+ return {
+ windowStates,
+ openWindows,
+ activeWindow,
+ roadMenuOpen,
+ shellReady,
+ clockText,
+ lucidiaStats,
+ roadchainStats,
+ walletStats,
+ minerStats,
+ menuRef,
+ menuButtonRef,
+ openWindow,
+ closeWindow,
+ minimizeWindow,
+ maximizeWindow,
+ startDrag,
+ focusWindow,
+ toggleRoadMenu,
+ taskbarToggle,
+ };
+}
diff --git a/br95/next-env.d.ts b/br95/next-env.d.ts
new file mode 100644
index 0000000..4f11a03
--- /dev/null
+++ b/br95/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/br95/next.config.mjs b/br95/next.config.mjs
new file mode 100644
index 0000000..3b18c5c
--- /dev/null
+++ b/br95/next.config.mjs
@@ -0,0 +1,9 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+ experimental: {
+ appDir: true,
+ },
+};
+
+export default nextConfig;
diff --git a/br95/package.json b/br95/package.json
new file mode 100644
index 0000000..dfb38c6
--- /dev/null
+++ b/br95/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "br95",
+ "version": "1.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "next": "14.2.3",
+ "react": "18.2.0",
+ "react-dom": "18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "20.12.7",
+ "@types/react": "18.2.79",
+ "typescript": "5.4.3"
+ }
+}
diff --git a/br95/tsconfig.json b/br95/tsconfig.json
new file mode 100644
index 0000000..f6962a8
--- /dev/null
+++ b/br95/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "baseUrl": "."
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}