17 KiB
PrivateGPT Workbench Style Guide
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.
Reference Assets
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.
Design Intent
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:
- Local-first AI utility.
- Technical power without intimidating non-technical users.
- A premium, public-brand-aligned experience.
- Simplicity and directness.
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
Visual Language
Use a dark, atmospheric workspace:
- Deep navy, charcoal, black, muted amber, and subtle purple/brown tones.
- Radial or blended gradients across the full viewport.
- A fine grain/noise texture over the background.
- Frosted glass panels with blur, light borders, and soft shadows.
- White primary text and muted gray secondary text.
- Small blue/orange/purple gradient accents inspired by the PrivateGPT/Zylon orb.
Avoid:
- Flat admin-dashboard gray.
- Marketing hero sections.
- Large decorative cards unrelated to function.
- Bright white page backgrounds.
- Excessive purple/blue gradient dominance.
- Heavy component-library appearance.
Layout
App Shell
Follow the structure in primary-chat-layout.png.
Recommended dimensions:
- Sidebar width:
286px(--sidebarvariable). - Main content max width for chat:
860px. - Composer width: aligned to chat content width.
- Full viewport height.
- No separate header bar unless needed.
The background should remain visible around and through glass surfaces.
Sidebar
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:
- Place the PrivateGPT logo at the top-left. In the single-file app, use the inline embedded SVG.
- Keep navigation compact and readable.
- Active item uses a brighter glass state.
- Chat rows should truncate long titles.
- No projects, folders, or chat grouping.
- Place API Debugger above Settings at the bottom of the sidebar.
- Place Settings below API Debugger in the bottom sidebar group.
- Place the GitHub repository widget below Settings.
- Place the Not for Production disclosure below the GitHub widget.
- Avoid making the sidebar feel like an enterprise admin menu.
- The chat list fills all available vertical space between the nav buttons and the bottom group, using
flex: 1 1 0andmin-height: 0. - Apply scroll-aware top/bottom fade masks to the chat list using CSS
mask-imagewith--fade-top-stop/--fade-bot-stopcustom properties, updated on scroll.
Main Chat
The chat view should be centered and spacious.
Message behavior:
- User messages align right.
- Assistant messages align left.
- Bubbles use translucent glass fills.
- Assistant messages may include a small gradient orb/avatar.
- User messages may use a subtle avatar or label.
- Citations should appear inline as compact superscript-like markers or small chips.
- Tool activity should appear as subdued inline status blocks, not large cards.
- Apply scroll-aware top/bottom fade masks to the messages list using the same
mask-imagepattern as the chat list.
Composer
Use chat-tools-composer.png as the main composer reference.
The composer should include:
- Large text input area.
- Send icon button on the right.
- Compact controls below the textarea:
- Model selector (custom glass dropdown — see Model Selector section).
- Refresh models icon button.
- Thinking toggle button.
- Tools selector button opening the Tools menu.
The Tools control should expose chat-specific toggles:
- Documents
- Web
- Databases
- MCP
- Skills
- Custom Tools
Selected context items can appear as compact chips.
Context Screen
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:
- Glass list rows.
- File/source icons.
- Type badges.
- Status metadata.
- Overflow menus.
- Nested or grouped rows where useful.
Documents
Rows should show:
- Icon.
- Name.
- Collection.
- File type badge, such as
PDF,DOCX,CSV,HTML. - Status, such as
Indexed,Processing,Failed. - Overflow menu: Preview, Search, Delete.
The Collection field is in Settings, not in the Documents panel. It applies globally to all document operations.
Databases
Rows should show:
- Database icon.
- Friendly name.
- Host or short connection label.
- Schema/table metadata if available.
- Overflow menu: Edit, Test, Delete.
Web, MCP, Skills, Custom Tools
Use the same row/card language:
- Name.
- Description or provider.
- Configuration summary.
- Overflow actions.
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 Screen
Settings owns Workbench-level connection configuration:
- PrivateGPT API base URL.
- Optional HTTP Basic auth (username and password fields displayed side by side).
- Optional system prompt.
- Optional workspace instructions for the current branded experience.
- Use citations toggle.
- Collection — the active document collection name used for all document operations and chat requests. This belongs in Settings, not in the Documents panel.
- Appearance controls for brand copy, palette, and optional visible sections.
- A control to rerun onboarding.
- Test API and Save buttons.
- Clear local data.
Onboarding Overlay
The first-run onboarding should feel like a guided setup sheet rather than a wizard from an enterprise admin console.
- Present it as a large glass overlay above the existing app shell so the user can feel that they are configuring the actual workspace.
- Step 1 should emphasize clarity and confidence: URL, auth, collection, then a simple checklist showing whether models, collection, and skills responded.
- Step 2 should feel lighter and optional: a prompt-driven generator plus editable result form on one side and a live preview tile on the other.
- The optional customization step should use the same visual language as Settings so the user understands both surfaces write to the same variables.
- GitHub / Zylon references are part of the demo identity and should not be removable through appearance customization.
API Debugger
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 requests.
- API responses.
- Errors.
- Redacted request headers.
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.
Not For Production Disclosure
The sidebar includes a compact Not for Production button below the GitHub widget.
Visual treatment:
- Same sidebar row rhythm as the GitHub widget.
- Slight warm/danger tint so it reads as an important disclosure without looking like an error.
- Info icon plus text label.
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).
GitHub Widget
The sidebar includes a clickable GitHub widget below Settings.
Requirements:
- Link to
https://github.com/zylon-ai/private-gpt. - Show the GitHub icon, label, star icon, and live star count when available.
- If the star fetch fails, keep the widget usable and show a neutral
Starslabel.
URL Hash Navigation
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.
Components
Glass Surface
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);
}
Background
: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;
}
Model Selector
Replace the native <select> with a custom glass dropdown:
- A
ghost-buttonshowing a CPU icon, the current model name (truncated), and an animated chevron. - Clicking opens a
.model-dropdownpanel positioned above the composer. - The dropdown lists all models as
.model-optionrows with a checkmark on the active selection. - Close on outside click or Escape.
- The
.model-dropdownis in the shared glass group and gets the stronger frost override.
Tools Menu
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.
Toggle Switches
All input[type="checkbox"] elements are styled as custom pill toggles — no native appearance:
- Pill track:
34 × 20px, rounded. - Knob:
12pxcircle, vertically centered. - Off state: muted white track and knob.
- On state: blue tint track (
rgba(80, 150, 255, 0.32)) with a bright knob (rgba(150, 205, 255, 0.96)). - Smooth
lefttransition on the knob (nottransform: translateX).
Thinking Button
The Extended Thinking toggle in the composer uses:
- A
ghost-buttonwith azapicon and the labelThinking. - Inactive: standard ghost button appearance with purple hover hint.
- Active: purple border, purple-tinted background, soft glow, and purple-tinted icon.
.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
Buttons and chips should feel like part of the glass environment:
- Thin border.
- Translucent fill.
- Slightly brighter hover.
- Clear active state with
scale(0.97)press feedback. - Icons where useful.
Use icons for:
- Send.
- Search.
- Files/collection.
- Tools.
- Database.
- More menu.
- Delete.
- Refresh/test.
- CPU (model selector).
- Chevron-down (model selector dropdown indicator).
- Check (selected item in model dropdown).
- Zap (thinking toggle).
If no icon library is used, inline SVGs are acceptable, but keep them minimal.
Menus And Overlays
Use search-overlay.png as reference.
Requirements:
- Glass overlay panel with the stronger frost treatment.
- Strong border.
- Soft shadow.
- Large readable input for search-like overlays.
- Compact pill filters where needed.
- Results as clean rows.
Both .menu-panel and .model-dropdown share the same glass + stronger-frost override as .modal-card.
Scroll Fades
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).
Typography
Use a modern sans-serif stack:
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
Guidelines:
- Primary text: high contrast white.
- Secondary text: muted white/gray.
- Avoid oversized hero typography.
- Chat text should be comfortably readable.
- Context/debugger text can be denser.
- Do not use negative letter spacing.
- Do not scale font sizes with viewport width.
Responsive Behavior
Desktop is the primary target for v1.
Minimum behavior:
- At narrow widths, sidebar can collapse or become an overlay.
- Chat composer remains usable.
- Text must not overflow buttons, chips, or rows.
- Context rows should wrap metadata rather than clipping important labels.
Implementation Constraints
The visual system should not require a frontend framework.
Preferred implementation:
- Single static
./index.html. - Vanilla CSS variables.
- Small reusable CSS classes.
- Repeated HTML templates are acceptable.
- No design system extraction required.
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.