14 KiB
style_guide.md — derez.ai Visual Design Spec
Scope: tokens, typography, spacing, colour usage, and every UI component.
Animations and background effects (star-field, perspective grid, horizon glow) are intentionally excluded — seestyles.cssdirectly for those.
1. Design Tokens
All variables live in :root inside styles.css. Never hard-code hex values in HTML or JS — always use var(--token-name).
1.1 Colour palette
| Token | Hex / Value | Role |
|---|---|---|
--bg |
#000810 |
Page background — deepest layer |
--bg-card |
#010f20 |
App shell & auth card surface |
--bg-inner |
#000d1a |
Inner cards, tabs bar |
--bg-hover |
#001a30 |
Hover state fills, ghost button bg |
--bg-input |
#000813 |
Input, select, textarea background |
--border |
#0a3060 |
Default 1 px borders |
--border-hi |
rgba(0,245,255,0.45) |
Shell / auth card outer glow border |
--accent |
#00f5ff |
Electric cyan — primary brand colour |
--accent-dim |
#002535 |
Active tab fill, logo icon background |
--danger |
#ff3b3b |
Destructive actions, error states |
--danger-dim |
#3b0000 |
Error message background |
--success |
#00ff88 |
Positive indicators, active pulse dot |
--warning |
#ffaa00 |
Mid-range credit bar, contract warning |
--text |
#c8f0ff |
Primary readable text |
--text-muted |
#2e6a80 |
Labels, secondary text, placeholders |
1.2 Shadow
--shadow:
0 0 0 1px rgba(0, 245, 255, 0.25), /* inner border glow */
0 0 60px rgba(0, 245, 255, 0.12), /* wide cyan ambient */
0 28px 72px rgba(0, 0, 0, 0.9); /* depth shadow */
Used on .auth-card and .app-shell. Do not apply to inner cards — they use only --border.
1.3 Border radius
| Token | Value | Applied to |
|---|---|---|
--radius |
8px |
Cards, inputs, badges, modals |
Hard-coded 20px |
— | Pill shapes: agent tabs, user pill |
Hard-coded 6px |
— | Buttons (.btn) |
Hard-coded 4px |
— | Progress bars, small badges |
2. Typography
2.1 Font stack
font-family: "Courier New", Courier, monospace;
All UI text — body, labels, inputs, buttons — uses this monospace stack. This is a deliberate brand choice for the Digital Grid theme. No external fonts are loaded.
2.2 Type scale
| Usage | Size | Weight | Colour token |
|---|---|---|---|
Auth title (derez.ai) |
22px |
700 |
--text |
| Auth sub-heading | 13px |
400 |
--text-muted |
| App brand (upper-left) | 15px |
700 |
--accent |
| Card title | 13px |
600 |
--text |
| Body / general | 14px |
400 |
--text |
| Labels, secondary | 12px |
500 |
--text-muted |
| Monospace values (SSH, keys) | 11.5px |
400 |
--text |
| Hints / helper text | 11px |
400 |
--text-muted |
| Badges, tiny labels | 10–11px |
600 |
varies |
2.3 Letter spacing
- App brand:
1.5px(no text-transform — renders asderez.ailowercase) - Card titles, tab labels: default (
0) - Panel-header uppercase labels (e.g. "Support Chat"):
0.6px
3. Spacing
The layout uses a consistent 4-point base grid. Common values:
| Value | Where used |
|---|---|
4px |
Tight gaps, small padding |
6px |
Button gaps, icon-text gap |
8px |
Toast padding, small card gap |
10px |
Form gap, tab gap |
12px |
Card body padding unit |
14px |
Card header margin-bottom, button padding |
16px |
Content grid gap, card padding |
18px |
Card padding (default), header horizontal padding |
20px |
Content grid padding |
22px |
Shell header horizontal padding |
4. Layout
4.1 Shell sizing
| Element | Size |
|---|---|
.app-shell |
min(1060px, 100vw − 16px) × min(780px, 100vh − 16px) |
.auth-card (narrow) |
min(440px, 100vw − 24px) |
.auth-card (auth-layout) |
min(1060px, 100vw − 16px) |
.app-header height |
54px |
.agent-tabs-bar height |
50px |
4.2 Content grid
.content-grid
display: grid
grid-template-columns: 1fr 1fr
gap: 16px
padding: 18px 20px
overflow-y: auto ← only this element scrolls
Collapses to single column below 700px viewport width.
5. Colour usage rules
Backgrounds (darkest → lightest)
--bg page background
└── --bg-card shell / auth card
└── --bg-inner inner cards, tabs bar
└── --bg-input inputs, textareas, code blocks
Use these in order. Never place --bg-card inside another --bg-card element — use --bg-inner for nested surfaces.
Text hierarchy
- Main content:
--text - Labels, secondary:
--text-muted - Accent / interactive:
--accent - Error:
--danger - Success:
--success
Borders
- Default borders between sections:
1px solid var(--border) - Highlight / outer glow borders (shell, modal):
1px solid var(--border-hi) - Focus state on inputs:
border-color: var(--accent)
6. Buttons
6.1 Variants
.btn-primary — outlined cyan (primary action)
background: transparent
color: #fff
border: 1px solid var(--accent)
box-shadow: 0 0 8px rgba(0,245,255,0.35), inset 0 0 8px rgba(0,245,255,0.04)
Hover: background: rgba(0,245,255,0.08) + brighter glow. opacity stays 1.
Use for: Open Agent, Sign In, Hire Agent, wizard Next, Send, Invite.
.btn-ghost — dark fill (secondary action)
background: var(--bg-hover)
color: var(--text)
border: 1px solid var(--border)
Hover: opacity: 0.85.
Use for: Restart Agent, Make Backup, Restore, Extend Contract, Cancel, all card-header utility actions.
.btn-danger — red fill (destructive confirm)
background: var(--danger)
color: #fff
Use for: the confirm-dialog "Confirm" button only. Never on card headers.
.btn-success — green fill
background: var(--success)
color: #000
Rarely used; reserved for exceptional positive completions.
6.2 Size modifiers
| Modifier | Padding | Font size | Use |
|---|---|---|---|
| (none) | 7px 14px |
13px |
Confirm dialog actions |
.btn-sm |
5px 10px |
12px |
Card header, inline |
.btn-block |
10px 14px |
14px |
Auth form full-width submit |
6.3 Rules
- Card-header buttons: text label only — no SVG icons.
- Two side-by-side header buttons: wrap in
<div style="display:flex;gap:8px;">. <a>tags acting as buttons: apply.btn .btn-ghost .btn-sm—.btnnulls the underline.- Loading state: call
btnLoad(btn, label)to disable + show spinner;btnReset(btn)to restore. - Disabled state:
opacity: 0.4; cursor: not-allowed.
7. Cards
Every content block is a .card.
<div class="card">
<div class="card-header">
<span class="card-title">
<svg width="14" height="14">…</svg>
Title
</span>
<!-- optional: <button class="btn btn-ghost btn-sm">Action</button> -->
</div>
<!-- card body content -->
</div>
| Property | Value |
|---|---|
| Background | var(--bg-inner) |
| Border | 1px solid var(--border) |
| Border-radius | var(--radius) = 8px |
| Padding | 16px 18px |
.card-full adds flex: 1 so the card stretches to fill remaining column height (used on Backups card).
Card title
.card-title {
display: flex;
align-items: center;
gap: 7px;
font-size: 13px;
font-weight: 600;
color: var(--text);
}
Icon size inside .card-title: always 14 × 14 px SVG, stroke="currentColor", stroke-width="2".
8. Forms & Inputs
8.1 Field structure
<div class="form-row"> <!-- optional row wrapper for side-by-side fields -->
<div class="form-group">
<label>Label text</label>
<input type="text" placeholder="…" />
</div>
</div>
| Property | Value |
|---|---|
| Label size | 12px, weight 500, colour --text-muted |
| Input bg | var(--bg-input) |
| Input border | 1px solid var(--border) |
| Input border-radius | 6px |
| Input padding | 9px 11px |
| Input font | 13px, var(--text) |
| Focus border | var(--accent) |
8.2 Inline save button (.pw-input-wrap)
Used when a save action lives inside the field (e.g. Instance Password, header comment password):
<div class="pw-input-wrap">
<input type="password" … />
<button class="pw-save-btn" style="display:none" …>
<!-- 14×14 checkmark SVG -->
</button>
</div>
The .pw-save-btn is position: absolute; right: 6px, shown/hidden by JS based on field content. Colour: --accent.
8.3 Textarea
Same rules as input. resize: vertical only. Font: monospace 12px.
8.4 Select
Same visual as input. Options background: var(--bg-card).
9. Data display rows
9.1 Server info rows
<div class="server-info-row">
<span class="server-info-label">Agent Type</span>
<span class="server-info-val">hermes</span>
</div>
- Label:
12px,--text-muted, capitalised - Value:
11.5px,--text, monospace - Separator:
border-top: 1px solid var(--border) - Clickable row (SSH Access): add
.server-info-row--copy— hover turns value--accentwith underline
9.2 Backup rows
<div class="backup-row">
<div class="backup-info">
<div class="backup-name">backup-2024-01-15</div>
<div class="backup-date">15 Jan 2024, 14:32</div>
</div>
<button class="btn btn-ghost btn-sm">Restore</button>
</div>
- Name:
13px, weight500,--text - Date:
11px,--text-muted - List scrolls internally at
max-height: 320px
9.3 API Key rows
Key row shows: name + monospace label + credit progress bar + Buy Credits button.
Progress bar colour by usage:
< 50 %→.prog-low(--successgreen)50–79 %→.prog-mid(--warningamber)≥ 80 %→.prog-high(--dangerred)
10. Status indicators
10.1 Pulse dot (online indicator)
<span class="pulse-dot"></span>
7pxcircle,background: var(--success), CSSpulseanimation- Used in user-pill (header) and agent tabs
10.2 Contract / status dots
<span class="contract-dot contract-dot--green"></span> <!-- active contract -->
<span class="contract-dot contract-dot--yellow"></span> <!-- expiring -->
<span class="contract-dot contract-dot--red"></span> <!-- expired / none -->
9px circle with a matching box-shadow ring at 20 % opacity.
11. Navigation — Agent tabs
<button class="agent-tab active">
<span class="agent-tab-dot"></span>
Agent Name
<span class="agent-tab-badge">fr</span>
</button>
| State | Style |
|---|---|
| Default | border: 1px solid var(--border), color: --text-muted, transparent bg |
| Hover | border-color: rgba(0,245,255,0.4), bg: --bg-hover, color: --text |
| Active | bg: --accent-dim, border: --accent, color: --accent |
.agent-tab-badge (region code): 10px, weight 600, bg: --bg-hover default, bg: rgba(0,245,255,0.2) when active.
12. Progress bars
<div class="prog-wrap">
<div class="prog-bar prog-low" style="width: 42%"></div>
</div>
- Track:
bg: --bg-input,height: 4px,border-radius: 4px - Fill:
height: 100%,border-radius: 4px,transition: width 0.5s ease - Colour class:
.prog-low/.prog-mid/.prog-high(see §9.3)
13. Loading & feedback
13.1 Loading rows
<div class="loading-row"><div class="spinner"></div></div>
Centred, padding: 20px. The spinner is 18px, border: 2px solid var(--border), border-top-color: var(--accent).
.spinner-sm (13 px) goes inside a button during btnLoad().
13.2 Toast notifications
Call toast(message, type) — never create toast HTML manually.
type |
Left-border colour |
|---|---|
'info' |
--accent |
'success' |
--success |
'error' |
--danger |
'warning' |
--warning |
Toast body: bg: --bg-card, border: 1px solid --border, border-radius: --radius, auto-removes after 4 s.
13.3 Confirm dialog (modal)
const ok = await confirmDialog('Title', 'Message explaining the action.');
if (!ok) return;
Modal: bg: --bg-card, border: --border-hi, border-radius: 12px. Footer has Cancel (.btn-ghost) + Confirm (.btn-danger).
14. Header layout
.app-header (54px tall, padding: 0 22px)
├── .app-brand ← "derez.ai" lowercase, --accent, 15px bold, letter-spacing 1.5px
├── .header-comment ← centred, flex:1, editable agent name label
└── .app-user
├── .user-pill ← pulse-dot + email, border: --border, hover: --accent
└── .btn.btn-ghost.btn-sm ← "Sign Out"
Header background: linear-gradient(90deg, rgba(0,245,255,0.08), transparent 60%) + border-bottom: 1px solid var(--border-hi).
15. Auth card
Auth card exists in two layouts controlled by the body.auth-layout class added by JS:
| Mode | Width | Layout |
|---|---|---|
| Narrow (no class) | min(440px, 100vw−24px) |
Single column — tab toggle shows Sign In / Hire Agent |
| Wide (auth-layout) | min(1060px, 100vw−16px) |
Two panes side-by-side, tab toggle hidden |
Pricing badge (wide mode only): bg: --accent-dim, border: 1px solid rgba(0,245,255,0.35), border-radius: --radius.
16. Rules for new components
- Backgrounds: use
--bg-innerfor cards nested inside the shell. Use--bg-inputfor text entry surfaces only. - Borders: always
1px solid var(--border)for structure;var(--border-hi)for emphasis (outer glow, focus rings on major panels). - Text: never set a custom colour — use only
--text,--text-muted,--accent,--danger,--success,--warning. - Icons in titles: always
14 × 14 px,stroke="currentColor",stroke-width="2". - Inline colour values in JS are allowed only in
renderKeys()andrenderContract()for dynamic progress/status colours. - No raw hex values anywhere else in HTML or JS.