botui/ui/suite/partials/desktop-inner.html
Rodrigo Rodriguez (Pragmatismo) 2f53b65aeb feat(ui): implement Window Manager desktop shell based on BUILD V3 design
- Built custom vanilla JS Window Manager (window-manager.js)
- Replaced default.gbui with new desktop.html featuring Windows 95 spatial metaphor + Tailwind aesthetics
- Redesigned icons, taskbar, sidebar, and workspace to exactly match the target PDF layout
- Migrated Chat, Tasks, and Terminal into pure HTMX fragments to load seamlessly inside floating panels
- Added missing CSS rules to handle window rendering without CDNs
2026-02-24 19:02:48 -03:00

198 lines
No EOL
12 KiB
HTML

<style>
/* CRITICAL: Overriding default Tailwind resets that break the layout */
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Fira Code', 'Fira Sans', Arial, sans-serif !important;
background: white !important;
overflow: hidden !important;
height: 100vh !important;
width: 100vw !important;
display: flex !important;
}
/* Core Layout replicating BUILD V3 screenshot styling */
.build-container { width: 100%; height: 100vh; display: flex; position: absolute; inset: 0; z-index: 1000; background: white;}
/* Left Sidebar */
.sidebar { width: 51px; height: 100vh; background: #f8f8f8; border-right: 1px solid #f0f1f2; display: flex; flex-direction: column; z-index: 100; }
.sidebar-item { width: 51px; height: 50px; border-bottom: 1px solid #f0f1f2; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.15s ease; position: relative;}
.sidebar-item:hover { background: #ffffff; }
.sidebar-item.active { background: #ffffff; border-left: 3px solid #84d669; }
.sidebar-icon { width: 30px; height: 30px; opacity: 0.6; }
.sidebar-item:hover .sidebar-icon { opacity: 1; }
/* Main Content wrapper */
.main-wrapper { flex: 1; display: flex; flex-direction: column; overflow: hidden; position: relative; }
/* Top Navigation Tabs */
.tabs-container { display: flex; flex-direction: column; background: #f8f8f8; border-bottom: 1px solid #f0f1f2; z-index: 100;}
.tabs-row { display: flex; height: 34px; }
.main-tab { height: 34px; min-width: 169px; flex: 1; border-right: 1px solid #f0f1f2; display: flex; align-items: center; padding: 0 18px; cursor: pointer; position: relative; }
.main-tab:hover { background: #ffffff; }
.main-tab.active { background: #84d669; border-color: #84d669;}
.main-tab.active .main-tab-content { color: white; }
.main-tab-content { display: flex; align-items: center; gap: 4px; font-family: 'Fira Code', monospace; font-size: 14px; font-weight: 500; color: #3b3b3b; }
/* Workspace (Where windows float) */
.workspace { flex: 1; display: flex; flex-direction: column; overflow: hidden; background: white; position: relative; z-index: 10;}
/* The Panel Grid (Desktop Icons) */
.panel-section { flex: 1; padding: 26px 33px; overflow-y: auto; z-index: 10; position: absolute; inset: 0; pointer-events: none;}
.panel-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; max-width: 1200px; pointer-events: auto;}
/* Interactive Desktop Icons triggering HTMX */
.desktop-icon {
background: white; border: 1px solid #f0f1f2; border-radius: 8px; height: 67px; padding: 10px;
display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start;
cursor: pointer; transition: all 0.2s ease; position: relative; width: 100%;
}
.desktop-icon:hover { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); transform: translateY(-2px); border-color: #84d669; }
.panel-card-icon { position: absolute; top: -20px; left: 10px; width: 42px; height: 42px; }
.panel-card-label { font-family: 'Fira Code', monospace; font-size: 13px; font-weight: 500; color: #3b3b3b; margin-top: auto; }
/* The background abstract pattern from BUILD V3 */
.bg-grid { position: absolute; inset: 0; background-image: linear-gradient(to right, #f0fdf4 1px, transparent 1px), linear-gradient(to bottom, #f0fdf4 1px, transparent 1px); background-size: 40px 40px; z-index: 0; pointer-events: none; }
.bg-svg { position: absolute; top: -10%; left: -10%; width: 120%; height: 120%; z-index: 0; opacity: 0.6; pointer-events: none; display: block !important;}
.bg-svg path { fill: none; stroke: #e6f2eb; stroke-width: 45; stroke-linecap: round; stroke-linejoin: round; }
.bg-svg path.inner { stroke: #f7faf9; stroke-width: 41; }
/* Bottom Taskbar */
.toolbar { height: 50px; background: white; border-top: 1px solid #f0f1f2; display: flex; align-items: center; padding: 0 8px; z-index: 100; position: relative;}
#taskbar-apps { display: flex; flex: 1; height: 100%; align-items: center; gap: 0px; }
.toolbar-time { font-family: 'Fira Code', monospace; font-size: 14px; color: #3b3b3b; text-align: right; line-height: 1.4; padding: 0 10px; margin-left: auto; }
/* Taskbar Items generated by WindowManager */
.taskbar-item { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.15s ease; border-bottom: 2px solid transparent;}
.taskbar-item:hover { background: #f8f8f8; }
.taskbar-item.active { border-bottom-color: #84d669; background: linear-gradient(to bottom, rgba(132,214,105,0) 50%, rgba(132,214,105,0.1) 100%); }
/* Utility */
svg { display: block; }
</style>
<div class="build-container">
<!-- Left Sidebar -->
<aside class="sidebar">
<div class="sidebar-item active" title="Home">
<svg class="sidebar-icon" viewBox="0 0 24 24" fill="none" stroke="#3b3b3b" stroke-width="2"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
</div>
<div class="sidebar-item" title="Terminal">
<svg class="sidebar-icon" viewBox="0 0 24 24" fill="none" stroke="#3b3b3b" stroke-width="2"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg>
</div>
</aside>
<!-- Main Wrapper -->
<div class="main-wrapper">
<!-- Top Navigation Tabs -->
<div class="tabs-container">
<div class="tabs-row">
<div class="main-tab active"><div class="main-tab-content"><span>//</span><span>BUILD</span></div></div>
<div class="main-tab"><div class="main-tab-content"><span>//</span><span>REVIEW</span></div></div>
<div class="main-tab"><div class="main-tab-content"><span>//</span><span>DEPLOY</span></div></div>
<div class="main-tab"><div class="main-tab-content"><span>//</span><span>MONITOR</span></div></div>
</div>
</div>
<!-- Workspace container where WindowManager operates -->
<div class="workspace" id="desktop-content-inner">
<!-- Background Pattern -->
<div class="bg-grid"></div>
<svg class="bg-svg" preserveAspectRatio="xMidYMid slice" viewBox="0 0 1000 600">
<path d="M-50,200 Q200,100 400,250 T800,50 T1100,250" />
<path d="M100,-50 Q250,200 150,450 T400,650" />
<path d="M500,-50 Q450,250 800,350 T750,700" />
<path class="inner" d="M-50,200 Q200,100 400,250 T800,50 T1100,250" />
<path class="inner" d="M100,-50 Q250,200 150,450 T400,650" />
<path class="inner" d="M500,-50 Q450,250 800,350 T750,700" />
</svg>
<div class="panel-section">
<div class="panel-grid">
<!-- HTMX Enabled Desktop Icons that WindowManager catches -->
<div class="desktop-icon" data-app-id="vibe" data-app-title="Vibe" hx-get="/suite/partials/chat.html" hx-swap="none">
<svg class="panel-card-icon" viewBox="0 0 42 42" fill="none">
<circle cx="21" cy="21" r="20" stroke="#84d669" stroke-width="2"/>
<path d="M14 21h14M21 14v14" stroke="#84d669" stroke-width="2"/>
</svg>
<div class="panel-card-label">Mantis</div>
</div>
<div class="desktop-icon" data-app-id="tasks" data-app-title="Tasks" hx-get="/suite/partials/tasks.html" hx-swap="none">
<svg class="panel-card-icon" viewBox="0 0 42 42" fill="none">
<rect x="2" y="2" width="38" height="38" rx="4" stroke="#3b3b3b" stroke-width="2"/>
<line x1="12" y1="12" x2="30" y2="12" stroke="#3b3b3b" stroke-width="2"/>
<line x1="12" y1="21" x2="30" y2="21" stroke="#3b3b3b" stroke-width="2"/>
<line x1="12" y1="30" x2="24" y2="30" stroke="#3b3b3b" stroke-width="2"/>
</svg>
<div class="panel-card-label">Tasks</div>
</div>
<div class="desktop-icon" data-app-id="terminal" data-app-title="Terminal" hx-get="/suite/partials/terminal.html" hx-swap="none">
<svg class="panel-card-icon" viewBox="0 0 42 42" fill="none">
<rect x="2" y="4" width="38" height="34" rx="4" stroke="#3b3b3b" stroke-width="2"/>
<line x1="10" y1="14" x2="32" y2="14" stroke="#3b3b3b" stroke-width="2"/>
<line x1="10" y1="22" x2="28" y2="22" stroke="#3b3b3b" stroke-width="2"/>
<line x1="10" y1="30" x2="24" y2="30" stroke="#3b3b3b" stroke-width="2"/>
</svg>
<div class="panel-card-label">Terminal</div>
</div>
<div class="desktop-icon" data-app-id="explorer" data-app-title="Explorer" hx-get="/suite/partials/explorer.html" hx-swap="none">
<svg class="panel-card-icon" viewBox="0 0 42 42" fill="none">
<rect x="2" y="2" width="38" height="38" rx="4" stroke="#3b3b3b" stroke-width="2"/>
<line x1="10" y1="10" x2="32" y2="10" stroke="#3b3b3b" stroke-width="2"/>
<line x1="10" y1="18" x2="28" y2="18" stroke="#3b3b3b" stroke-width="2"/>
<line x1="10" y1="26" x2="32" y2="26" stroke="#3b3b3b" stroke-width="2"/>
<line x1="10" y1="34" x2="24" y2="34" stroke="#3b3b3b" stroke-width="2"/>
</svg>
<div class="panel-card-label">Explorer</div>
</div>
<div class="desktop-icon" data-app-id="editor" data-app-title="Editor" hx-get="/suite/partials/editor.html" hx-swap="none">
<svg class="panel-card-icon" viewBox="0 0 42 42" fill="none">
<polyline points="4 8 12 2 20 8" stroke="#3b3b3b" stroke-width="2"/>
<line x1="12" y1="2" x2="12" y2="24" stroke="#3b3b3b" stroke-width="2"/>
<polyline points="22 16 30 10 38 16" stroke="#3b3b3b" stroke-width="2"/>
<line x1="30" y1="10" x2="30" y2="32" stroke="#3b3b3b" stroke-width="2"/>
</svg>
<div class="panel-card-label">Editor</div>
</div>
<div class="desktop-icon" data-app-id="browser" data-app-title="Browser" hx-get="/suite/partials/browser.html" hx-swap="none">
<svg class="panel-card-icon" viewBox="0 0 42 42" fill="none">
<rect x="2" y="4" width="38" height="34" rx="4" stroke="#3b3b3b" stroke-width="2"/>
<circle cx="14" cy="16" r="4" stroke="#3b3b3b" stroke-width="2"/>
<path d="M6 34a6 6 0 0 1 6-6h10a6 6 0 0 1 6 6v2H6v-2z" stroke="#3b3b3b" stroke-width="2"/>
</svg>
<div class="panel-card-label">Browser</div>
</div>
</div>
</div>
</div>
<!-- Bottom Taskbar -->
<footer class="toolbar" id="taskbar">
<div id="taskbar-apps">
<!-- Taskbar items populated automatically by window-manager.js -->
</div>
<div class="toolbar-time">
<div id="clock-time">00:00</div>
<div id="clock-date">01/01/2026</div>
</div>
</footer>
</div>
</div>
<!-- HTMX Intercepts and WindowManager Init as described in UI.md Phase 3 -->
<script>
// Simple Clock implementation matching the screenshot bottom right corner
setInterval(() => {
const now = new Date();
const timeEl = document.getElementById('clock-time');
const dateEl = document.getElementById('clock-date');
if(timeEl) timeEl.textContent = now.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
if(dateEl) dateEl.textContent = now.toLocaleDateString();
}, 1000);
</script>