Files
oliver f5c9bb6a35 style
2026-06-08 09:02:07 -03:00

14 KiB
Raw Permalink Blame History

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

--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 1011px 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)

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.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.

<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 --accent with 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, 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)
  • 5079 %.prog-mid (--warning amber)
  • ≥ 80 %.prog-high (--danger red)

10. Status indicators

10.1 Pulse dot (online indicator)

<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

<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, 100vw24px) Single column — tab toggle shows Sign In / Hire Agent
Wide (auth-layout) min(1060px, 100vw16px) 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.