style
This commit is contained in:
+480
@@ -0,0 +1,480 @@
|
||||
# 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 — see `styles.css` directly 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
|
||||
|
||||
```css
|
||||
--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
|
||||
|
||||
```css
|
||||
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 as `derez.ai` lowercase)
|
||||
- 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)
|
||||
```css
|
||||
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)
|
||||
```css
|
||||
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)
|
||||
```css
|
||||
background: var(--danger)
|
||||
color: #fff
|
||||
```
|
||||
**Use for:** the confirm-dialog "Confirm" button only. Never on card headers.
|
||||
|
||||
#### `.btn-success` — green fill
|
||||
```css
|
||||
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` — `.btn` nulls 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`.
|
||||
|
||||
```html
|
||||
<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
|
||||
|
||||
```css
|
||||
.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
|
||||
|
||||
```html
|
||||
<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):
|
||||
|
||||
```html
|
||||
<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
|
||||
|
||||
```html
|
||||
<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 `--accent` with underline
|
||||
|
||||
### 9.2 Backup rows
|
||||
|
||||
```html
|
||||
<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`, weight `500`, `--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` (`--success` green)
|
||||
- `50–79 %` → `.prog-mid` (`--warning` amber)
|
||||
- `≥ 80 %` → `.prog-high` (`--danger` red)
|
||||
|
||||
---
|
||||
|
||||
## 10. Status indicators
|
||||
|
||||
### 10.1 Pulse dot (online indicator)
|
||||
|
||||
```html
|
||||
<span class="pulse-dot"></span>
|
||||
```
|
||||
|
||||
- `7px` circle, `background: var(--success)`, CSS `pulse` animation
|
||||
- Used in user-pill (header) and agent tabs
|
||||
|
||||
### 10.2 Contract / status dots
|
||||
|
||||
```html
|
||||
<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
|
||||
|
||||
```html
|
||||
<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
|
||||
|
||||
```html
|
||||
<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
|
||||
|
||||
```html
|
||||
<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)
|
||||
|
||||
```js
|
||||
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
|
||||
|
||||
1. **Backgrounds:** use `--bg-inner` for cards nested inside the shell. Use `--bg-input` for text entry surfaces only.
|
||||
2. **Borders:** always `1px solid var(--border)` for structure; `var(--border-hi)` for emphasis (outer glow, focus rings on major panels).
|
||||
3. **Text:** never set a custom colour — use only `--text`, `--text-muted`, `--accent`, `--danger`, `--success`, `--warning`.
|
||||
4. **Icons in titles:** always `14 × 14 px`, `stroke="currentColor"`, `stroke-width="2"`.
|
||||
5. **Inline colour values in JS** are allowed only in `renderKeys()` and `renderContract()` for dynamic progress/status colours.
|
||||
6. **No raw hex values** anywhere else in HTML or JS.
|
||||
Reference in New Issue
Block a user