ui/docs/STYLE_GUIDE.md
This guide defines the visual and UX direction for PrivateGPT Workbench. It complements the product requirements in docs/PRD.md.
The goal is to keep the implementation simple while aligning the demonstrator with the public-facing PrivateGPT/Zylon visual language.
Use these repo-local images as visual references:
| Reference | File | Purpose |
|---|---|---|
| Primary chat layout | ../references/primary-chat-layout.png | Main reference for sidebar, chat layout, message bubbles, and composer placement. |
| Search overlay | ../references/search-overlay.png | Reference for modal/search overlays, large glass panels, tabs/chips, and filtered result lists. |
| Chat tools composer | ../references/chat-tools-composer.png | Reference for the chat composer, file/tool controls, message density, and chat bubble treatment. |
| Context knowledge base | ../references/context-knowledge-base.png | Reference for Context rows, source lists, file badges, overflow menus, and glass list surfaces. |
The PrivateGPT logo should be embedded directly in ./index.html as inline SVG so the page does not depend on an external logo asset at runtime.
PrivateGPT Workbench should feel like a polished local AI workspace, not a generic admin console and not a marketing landing page.
The interface should communicate:
The product surface remains:
Sidebar
Context
New Chat
Chat list
API Debugger
Settings
GitHub
Not for Production
Main
Context screen
or
API Debugger screen
or
Settings screen
or
Chat screen
Use a dark, atmospheric workspace:
Avoid:
Follow the structure in primary-chat-layout.png.
Recommended dimensions:
286px (--sidebar variable).860px.The background should remain visible around and through glass surfaces.
The sidebar should be a vertical frosted-glass panel.
Content:
PrivateGPT logo
Context
New Chat
Chats
Chat title
Chat title
Chat title
API Debugger
Settings
GitHub
Not for Production
Requirements:
flex: 1 1 0 and min-height: 0.mask-image with --fade-top-stop/--fade-bot-stop custom properties, updated on scroll.The chat view should be centered and spacious.
Message behavior:
mask-image pattern as the chat list.Use chat-tools-composer.png as the main composer reference.
The composer should include:
The Tools control should expose chat-specific toggles:
Selected context items can appear as compact chips.
The Context screen defines what the assistant can access. It should look like a source manager, not a settings page.
Sections:
Documents
Databases
Web
MCP
Skills
Custom Tools
Use context-knowledge-base.png as the reference for:
Rows should show:
PDF, DOCX, CSV, HTML.Indexed, Processing, Failed.The Collection field is in Settings, not in the Documents panel. It applies globally to all document operations.
Rows should show:
Use the same row/card language:
The Web section is informational only. Do not collect provider credentials in Workbench; web provider and API key configuration belongs in the PrivateGPT backend.
Custom Tools should not be hidden behind an "Advanced" label. They are a first-class Context section.
Settings owns Workbench-level connection configuration:
The first-run onboarding should feel like a guided setup sheet rather than a wizard from an enterprise admin console.
API Debugger appears as a sidebar destination above Settings.
It is session-level, live-only, and ephemeral.
Recommended layout:
Timeline list | Event detail panel
Use the same glass styling, but make it denser and more technical than Chat.
API Debugger should show:
API Debugger events must not persist across page reloads.
Both the timeline panel and the detail panel must have min-width: 0 so long URLs truncate instead of overflowing the panel.
The sidebar includes a compact Not for Production button below the GitHub widget.
Visual treatment:
Clicking it opens a glass-style modal. The title should be:
This demonstrator is not intended for Production use
Keep the body concise, with four merged bullets covering browser localStorage secrets, lack of access control, visible debugger data, and browser-executed custom tools. End with links to Zylon (https://zylon.ai) and the demo booking page (https://cal.com/zylon/demo?source=privategptui).
The sidebar includes a clickable GitHub widget below Settings.
Requirements:
https://github.com/zylon-ai/private-gpt.Stars label.The app uses hash-based navigation so reloading restores the current view.
Hash format:
| Hash | View |
|---|---|
#context/documents | Context — Documents tab |
#context/databases | Context — Databases tab |
#context/web | Context — Web tab |
#context/mcp | Context — MCP tab |
#context/skills | Context — Skills tab |
#context/customTools | Context — Custom Tools tab |
#settings | Settings screen |
#apiDebugger | API Debugger screen |
#chat/{chatId} | Specific chat by ID |
syncHash() calls history.replaceState at the end of every render() call. restoreFromHash() runs at startup before the first render and on hashchange events for browser back/forward support.
All main panels share one glass treatment via a shared CSS selector group:
.settings-card,
.context-panel,
.debug-panel,
.composer,
.message-bubble,
.menu-panel,
.model-dropdown,
.modal-card {
background:
linear-gradient(135deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.055));
border: 1px solid var(--border);
box-shadow: 0 18px 60px rgba(0, 0, 0, 0.28);
backdrop-filter: blur(22px);
-webkit-backdrop-filter: blur(22px);
}
Floating panels (modal card, tools menu, model dropdown) override with a light translucent frost, very heavy blur, heavier at the bottom:
.modal-card,
.menu-panel,
.model-dropdown {
background: linear-gradient(to bottom,
rgba(255, 255, 255, 0.14) 0%,
rgba(255, 255, 255, 0.26) 100%
);
backdrop-filter: blur(72px) saturate(1.6);
-webkit-backdrop-filter: blur(72px) saturate(1.6);
}
The white-glass tint stays light (translucent, not opaque); the blur(72px) defocuses the background enough to make text readable; the gradient is heavier at the bottom for visual grounding.
The modal backdrop itself uses a moderate blur:
.modal-backdrop {
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
}
:root {
--bg: #090b12;
--text: #f7f7fb;
--muted: rgba(255, 255, 255, 0.58);
--muted-strong: rgba(255, 255, 255, 0.74);
--faint: rgba(255, 255, 255, 0.36);
--glass: rgba(255, 255, 255, 0.1);
--glass-soft: rgba(255, 255, 255, 0.07);
--glass-strong: rgba(255, 255, 255, 0.16);
--border: rgba(255, 255, 255, 0.24);
--border-soft: rgba(255, 255, 255, 0.14);
--shadow: 0 24px 80px rgba(0, 0, 0, 0.38);
--danger: #ff9f9f;
--ok: #91e8bd;
--warn: #ffd18a;
--accent: #f0a247;
--blue: #70b7ff;
--radius-xl: 32px;
--radius-lg: 24px;
--radius-md: 16px;
--radius-sm: 10px;
--sidebar: 286px;
}
body {
background:
radial-gradient(circle at 17% 78%, rgba(36, 125, 190, 0.58), transparent 36%),
radial-gradient(circle at 83% 16%, rgba(212, 148, 63, 0.38), transparent 31%),
radial-gradient(circle at 53% 42%, rgba(92, 50, 116, 0.34), transparent 40%),
linear-gradient(135deg, #081427 0%, #15121c 42%, #130b05 100%);
}
body::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
opacity: 0.24;
background-image:
radial-gradient(rgba(255,255,255,0.18) 0.65px, transparent 0.65px);
background-size: 3px 3px;
mix-blend-mode: overlay;
}
Replace the native <select> with a custom glass dropdown:
ghost-button showing a CPU icon, the current model name (truncated), and an animated chevron..model-dropdown panel positioned above the composer..model-option rows with a checkmark on the active selection..model-dropdown is in the shared glass group and gets the stronger frost override.The Tools popup (.menu-panel) is structured with section groups:
Knowledge
Documents [toggle]
Web [toggle]
Databases [group title]
item [toggle]
MCP [group title]
...
Skills [group title]
...
Custom Tools [group title]
...
Each group uses .menu-group and .menu-group-title (small uppercase label). Toggle rows inside the menu are borderless with hover highlight only, distinguishing them from Settings card toggle rows which retain a border.
All input[type="checkbox"] elements are styled as custom pill toggles — no native appearance:
34 × 20px, rounded.12px circle, vertically centered.rgba(80, 150, 255, 0.32)) with a bright knob (rgba(150, 205, 255, 0.96)).left transition on the knob (not transform: translateX).The Extended Thinking toggle in the composer uses:
ghost-button with a zap icon and the label Thinking..thinking-chip.active {
border-color: rgba(130, 80, 230, 0.55);
background: rgba(100, 55, 200, 0.18);
color: rgba(200, 165, 255, 0.95);
box-shadow: 0 0 14px rgba(120, 70, 220, 0.18);
}
Buttons and chips should feel like part of the glass environment:
scale(0.97) press feedback.Use icons for:
If no icon library is used, inline SVGs are acceptable, but keep them minimal.
Use search-overlay.png as reference.
Requirements:
Both .menu-panel and .model-dropdown share the same glass + stronger-frost override as .modal-card.
Apply a top/bottom scroll-aware fade mask to any scrollable list that may overflow:
.scrollable-wrap {
--fade-top-stop: 0px;
--fade-bot-stop: 0px;
mask-image: linear-gradient(
to bottom,
transparent 0,
black var(--fade-top-stop),
black calc(100% - var(--fade-bot-stop)),
transparent 100%
);
}
Update --fade-top-stop and --fade-bot-stop via JavaScript on scroll. Applied to:
.chat-list-wrap — sidebar chat list (22px stops)..messages — main message list (28px stops).Use a modern sans-serif stack:
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
Guidelines:
Desktop is the primary target for v1.
Minimum behavior:
The visual system should not require a frontend framework.
Preferred implementation:
./index.html.The styling should support the PRD's simplicity requirement: polished enough for a public-facing demo, but not architected like a long-term product frontend.