Files
helder/docs/design
Jonathan van Rij bccc97c11c
Some checks failed
CI / check (push) Has been cancelled
fixes and build 0.1.0
2026-09-04 09:43:04 +02:00
..
2026-09-03 09:36:58 +02:00
2026-09-03 09:36:58 +02:00
2026-09-04 09:43:04 +02:00
2026-09-04 09:43:04 +02:00
2026-09-03 09:36:58 +02:00

Handoff: Helder — editor for working with Claude Code

Overview

Helder is a desktop code editor built around one job: work on a codebase together with Claude Code. It replaces a general IDE with four columns — source control, explorer, editor, agent — plus five overlays (search, keyboard shortcuts, project note, project launcher, expanded diff) and a set of small surfaces (context menus, a pass-on-to-agent prompt, tooltips, a markdown preview).

This handoff describes one consistent visual system for all of those screens.

About the design files

The files in this bundle are design references written in HTML. They show the intended look, spacing and states. They are not production code to copy.

The task is to recreate these screens in the target codebase's own environment (Electron + React, Tauri + Svelte, SwiftUI, whatever the app already uses) with its established patterns. If no environment exists yet, pick the framework that fits a desktop editor and implement the design there.

Helder IDE.dc.html is a single-canvas board: every screen sits on one page, side by side, at real pixel sizes. Open it in a browser to inspect any value with devtools.

Fidelity

High fidelity. Colours, type, row heights, paddings, radii and states are final and exact. Recreate them pixel-for-pixel. Everything is authored with inline styles so any element's computed value can be read directly from the file.

Two things are deliberately not final:

  • The code shown inside the editor panes is sample content, not a spec.
  • Icons are Unicode stand-ins (⌕ ▤ ◇ ⧉ ✎ ↺ ⇄ ⑂ ◆ →). Ship them as Lucide glyphs at stroke width 1.75, 16px inline / 18px standalone.

Design tokens

Surfaces (four, no more)

Token Hex Use
editor #101720 Editor canvas, terminal, launcher backdrop, code blocks
panel #18202B Title bar, side panels, status bar, overlays, menus, tooltip host
raised #232C39 Selected row, hairline borders, tooltip surface, keycap borders
hover #1E2733 Row hover fill only

Text on dark

Token Hex Use
text-1 #F4F5F4 Active file, dialog titles, selected row
text-2 #E4E7E6 Body copy, code plain text
text-3 #BAC0C0 Inactive rows, identifiers, secondary copy
text-4 #6C7783 Labels, paths, meta, comments
text-5 #3A424C Line numbers, disabled

Accent — amber, reserved

#E8913A primary · #C4741F deep · #F0B476 soft · rgba(232,145,58,.10) tint · rgba(232,145,58,.22) focus ring.

Amber is allowed only for: the active toolbar toggle (tint fill), the 2px selection rule, the caret, keycap glyphs, the blinking period in the wordmark, the primary button fill (ink text on amber, never white), the search-hit highlight, section markers, list markers, links, and counts in the status bar. Never an amber panel, never an amber heading.

Light canvas (this board only)

#EFF0EE page · #E5E7E4 spec card · #CDD1CD hairline · #171C22 ink · #3A424C ink muted · #6B7480 ink dim. The application itself is dark only.

Syntax — six colours, all muted

Role Hex
plain / function name #E4E7E6
variable / property #BAC0C0
comment #6C7783
keyword / operator / pseudo-class #C3A6CE
string / value / type path #8FBFB4
number / tag / hex literal #F0B476

No bold, no italic in code. Weight stays 400 so the column reads flat.

Diff

  • added: text #8FBFB4, fill rgba(143,191,180,.12), 2px left rule #8FBFB4
  • removed: text #C4741F, fill rgba(196,116,31,.14), 2px left rule #C4741F
  • counts in headers: +1 in #8FBFB4, 1 in #C4741F (real minus sign U+2212)

No green, no red anywhere. The diff reads on shape and on the 2px rule.

Type

  • IBM Plex Mono — 400/500/600/700. All labels, paths, code, keycaps, titles, numbers.
  • IBM Plex Sans — 400/500. Rows, menu items, tooltips, buttons, running text.
Role Spec
Board display Mono 700, 58px/1.02, -0.04em
Section title Mono 700, 20px/1.2, -0.02em
Dialog title Mono 700, 14px/1
Section/panel label Mono 700, 10px, 0.14em, uppercase, #6C7783
Board label Mono 700, 1011px, 0.14em, uppercase, #6B7480
Code Mono 400, 13px / 20px line box
Search hit line Mono 400, 12px / 24px line box
Path / meta / status bar Mono 400, 1112px
Keycap Mono 600, 12px, padding 4px 6px, 1px #232C39, radius 2px, glyph #E8913A
Row label Sans 400 13px (500 when selected)
Body copy Sans 400, 14px/1.7, max 68ch
Tooltip Sans 400, 12px/1.5

Geometry

Value Where
24px Explorer / launcher-adjacent row height
26px Source-control row height
28px Status bar, state-specimen rows
30px Context-menu item height
34px Editor tab strip, markdown/code panel header
44px Title bar and toolbar
20px Code line box (13px type)
2px Radius: buttons, inputs, tags, keycaps, menus' inner rows, code blocks
4px Radius: panels, cards, menus
8px Radius: overlays (modals) only
1px Every hairline (#232C39 on dark, #CDD1CD on light)
2px Accent rule: selection, focus border, pull-quote
9999px Traffic-light dots and avatars only

Column widths in the workspace: source control 236 · explorer 288 · editor flex · agent 480. Agent terminal block 190px tall. Full frame 1760 × 1000.

Elevation

Only two shadows exist:

  • dropdown / context menu: 0 4px 16px rgba(23,28,34,.10)
  • overlay: 0 16px 48px rgba(23,28,34,.18)

No ambient card shadow, no glow.

Motion

Colour transitions only, 160ms cubic-bezier(0.22,1,0.36,1) (120ms on small controls). The single exception is blink: a stepped 1.1s on/off (no fade) used for the caret, the terminal block cursor and the amber period in the wordmark. No entrance animation, no lift, no scale, no parallax.


Screens

01 · Workspace (1760 × 1000)

Vertical stack: title bar 44px → body (flex row) → status bar 28px.

Title bar (#18202B, 1px bottom #232C39, padding 0 14px, gap 18px) Traffic lights 12px (#E8913A, #6C7783, #3A424C, gap 8px) · wordmark helder Mono 700 13px #F4F5F4 with a blinking . in #E8913A · project odynt Mono 12px #6C7783 · · · branch main Mono 500 12px #E8913A · breadcrumb of the open path in Mono 12px #6C7783, last segment #F4F5F4 600, separators · then the toolbar, right-aligned, gap 4px.

Toolbar toggle: label Sans 12px + keycap. Off = label #BAC0C0, no fill. On = fill rgba(232,145,58,.10), label #F4F5F4 500, keycap border rgba(232,145,58,.35). Hidden-files-off is the muted case: label and keycap both #6C7783. Toggles: Search ⌘F · Fluid ⌘L · Hidden ⌘. · Note ⌘N · Git ⌘G · ? (26px square, 1px border).

Source control column (236px, #18202B, 1px right border) Commit box: 52px #101720 field, 1px #232C39, radius 2, placeholder "Shift+Enter to commit" #6C7783; 34px push button beside it, same border. Group header: Mono 700 10px 0.14em uppercase #6C7783, count right in #E8913A ("STAGED CHANGES 4", "CHANGES 1"). Rows 26px: status letter (Mono 600 10px — staged #8FBFB4, unstaged #F0B476) · 8px type badge · file name Sans 12px, ellipsised. Footer line "4 staged · 1 unstaged" Mono 11px #6C7783.

Explorer (288px, #18202B) — 30px header ("EXPLORER" / project name), then 24px rows. Indent 16px per level (12 · 28 · 44 · 60 · 76 padding-left). Collapsed #6C7783; expanded #E8913A, its label #F4F5F4. File rows carry an 8px type badge and, when dirty, a trailing M in #8FBFB4.

Type badge: Mono 600 8px, ink text #101720 on a per-extension fill, radius 2, padding 3px 4px — php #C3A6CE · md #BAC0C0 · js #F0B476 · css #8FBFB4.

Editor (flex, #101720) — 34px strip: "MODIFIED" label, +1 / 1 counts, then a right-aligned segmented control (1px #232C39, radius 2, dividers 1px): Actual · Original · Diff · Split. Active segment = amber fill with #171C22 text. Code area: CSS grid 56px 1fr, line box 20px, numbers right-aligned #3A424C with 14px right padding. Indentation is padding-left on the code cell (7.82px per space: 31.3 / 62.6 / 93.8 / 125.1) — do not ship non-breaking spaces.

Agent panel (480px, #18202B, 1px left border) Header: 60px #232C39 square (mark), then Claude Code Mono 700 14px + version in #6C7783, model line Sans 12px #BAC0C0, cwd Mono 12px #6C7783. Notice strip: fill rgba(232,145,58,.10), [ ! ] Mono 600 12px #E8913A, sentence Sans 12px, inline command in Mono #F0B476. Transcript: user turn prefixed in #E8913A, agent turn in #6C7783, text Sans 13px/1.6. Tool calls sit in a #101720 block, 1px #232C39: verb in #8FBFB4 (read) or #F0B476 (write), target and counts #6C7783. Prompt field: 44px, #101720, 2px #E8913A border + 0 0 0 2px rgba(232,145,58,.22) ring (this is the focus treatment everywhere), prefix, blinking 1px caret. Status line: Mono 11px #6C7783; project chip = amber fill with #171C22 text; ▸▸ auto mode in #E8913A; slash hint right. Terminal: 190px, #101720, Mono 12px/1.7 — [main] #8FBFB4, [~/path]$ #6C7783, output #6C7783, 7×14px blinking amber block cursor.

Status bar (28px, #18202B) — ⑂ main in #E8913A, +16 #8FBFB4, 12 #C4741F, then right-aligned path · Ln/Col · UTF-8 · LF · language (#BAC0C0).

02a · Search (⌘F)

Overlay: flat ink scrim rgba(16,23,32,.72) (no blur), 34px inset, panel #18202B, 1px #232C39, radius 8, overlay shadow.

  • Query bar 54px: #E8913A, query Mono 500 16px #F4F5F4, blinking caret; right side = extension filters (active = amber fill + ink text; inactive = 1px border, #BAC0C0) and a Mono 11px result summary #6C7783 behind a 1px left divider.
  • Three columns: this file (230px) · project (flex) · files (250px), split by 1px borders. Column headers are the standard 10px mono labels; the focused column's header is #E8913A with a count chip (amber fill, ink text).
  • Result group header: type badge + path Mono 12px #BAC0C0, hit count right #6C7783.
  • Hit lines: grid 64px 1fr, line box 24px. Match run = amber fill with #171C22 text on the selected row, #F0B476 text elsewhere. Selected row: #232C39 fill, 2px amber left rule, and the line number lifts to #E8913A (never leave it at #3A424C).
  • Empty column state: one plain sentence, Sans 12px #6C7783 ("No matches in this file." / "No file names match."). No illustration.
  • Footer 38px: key hints (⌘←/⌘→ column, ⌘↑/⌘↓ row, open) with amber glyphs, esc chip right.

02b · Keyboard shortcuts (?)

Same overlay shell. 50px header with #E8913A + "Keyboard shortcuts" + esc chip. Body groups (NAVIGATE, AGENT, GIT, FILE) each a 10px mono label, then a 92px 1fr grid: keycap cluster left (gap 4px), description Sans 13px #E4E7E6 right, 6px vertical padding per row.

02c · Project note (⌘N)

Same shell. Header: amber, "Note", filename .notes.txt Mono 12px #6C7783, then the primary button — amber fill, #171C22 text, Sans 500 12px, radius 2, padding 6px 10px, with a ⌘P keycap at Mono 600 11px — then the esc chip. Body: Mono 400 14px/1.7 #E4E7E6, max 68ch, 18px between paragraphs, blinking caret at the end of the text. Footer 34px: "saved on focus loss · 412 characters".

The note is plain text and it is the agent's input: ⌘P sends the whole note.

02d · Project launcher

Window #101720 with only traffic lights (34px), no title bar. Centred panel on #18202B, radius 8, overlay shadow, top-aligned with 20px/40px padding. Header: amber + wordmark with blinking period + "Open a project to begin" Sans 12px #6C7783. Then a 46px "Open new project…" row with + amber and an chip. RECENT label, then 38px rows: icon, name Sans 500 13px, path Mono 11px #6C7783. Selected row: #232C39, 2px amber left rule, icon and path lift one step. Footer 36px: ⌘↑↓ navigate · ↵ open.

03 · Expanded diff (1760 × 620)

Own window: 42px title bar (traffic lights, path Mono 500 12px #F4F5F4, "MODIFIED", +1 / 1, "staged → actual" Mono 11px #6C7783, and a right-aligned "Collapse esc" button with 1px border). Two panes split by a 1px border; each has a 30px header — left ORIGINAL + "before" #3A424C, right UPDATED in #E8913A + "after". Panes are grids 52px 1fr, line box 22px, indentation as padding-left, and identical line numbering in both panes so the eye can travel across. Changed row gets the fill, the 2px left rule and a lifted number colour.

04 · Small surfaces

Context menu (explorer and source control) — 320px, #18202B, 1px #232C39, radius 4, dropdown shadow, 8px vertical padding. First a path header (Mono 11px #6C7783, 1px bottom border). Items 30px, Sans 13px #BAC0C0, icon #6C7783. Highlighted item: #232C39 fill, 2px amber left rule, label #F4F5F4 500, icon amber. Destructive item ("Delete file", "Discard changes"): #C4741F label. Groups separated by a 1px rule with 6px margins.

Explorer items: Pass on reference · Copy reference · Pass on file name · Copy file name | Rename file · Show in Finder · Delete file. Source-control items: Pass on reference · Copy reference | Stage changes · Open diff · Discard changes.

Pass on to agent — 460px panel, 14px padding, gap 12. Title row ( amber + Mono 700 13px + esc chip), a focused 38px input (2px amber border + ring, blinking caret), then an INSERTS preview: 10px mono label + the composed string on an amber fill with #171C22 text, radius 2, ellipsised. Footer hint ↵ insert into agent · esc cancel with amber glyphs.

Tooltip#232C39 surface, 1px #3A424C, radius 2, padding 8px 10px, max 300px, Sans 12px/1.5 #E4E7E6. No arrow, no shadow. The current state is named inside the sentence in amber ("Hidden files: hidden — …", "Column widths: fluid — …"), then one sentence saying what a click does.

Markdown Actual / Preview — same 34px header on both halves; the segmented control's active side is the amber fill. Actual = the code grid (44px 1fr, line box 20px) with ## headings in #F0B476. Preview: 18px/20px padding, max 68ch, Sans 13px/1.7 body, Mono 700 headings with a 1px #232C39 underline.

06 · Code colours and markdown preview

Four specimens at 620px: a JS module, a PHP class, a CSS file and the full markdown preview. Each panel: 34px header with type badge, path Mono 500 12px, and a right language label (or the Actual/Preview control).

The markdown preview is the reading surface, so it is the one place where Sans body copy gets room:

  • eyebrow: 10px mono label #6C7783
  • h2: Mono 700 24px/1.1, -0.03em, #F4F5F4
  • h3: Mono 700 17px/1.2 with a 1px #232C39 underline, 8px below the text
  • paragraph: Sans 14px/1.7 #E4E7E6, max 68ch, text-wrap: pretty
  • list: flex rows, gap 10, marker in #E8913A (never a bullet, never an emoji)
  • inline code: Mono 13px #F0B476 on #18202B, 1px #232C39, radius 2, padding 1px 5px
  • block quote: 2px amber left rule, 16px left padding, Sans italic 15px #F0B476
  • code block: #18202B, 1px #232C39, radius 2, padding 14px 16px, Mono 13px/20px, syntax palette as above
  • table: 1px #232C39 container, radius 2; header row on #18202B with 10px mono labels; body rows Sans 13px #BAC0C0, cells 10px 14px, 1px row rules; state words use #8FBFB4 (done) and #E8913A (open)
  • link: #E8913A with a 1px #232C39 bottom border; hover lifts the text to #F4F5F4 and the border to #E8913A. marks forward action.

Interactions and behaviour

Trigger Result
⌘F Search overlay, query seeded from the editor selection
⌘↑ / ⌘↓ Move the row cursor in the focused list
⌘← / ⌘→ Move focus between search columns
Open the selected row (search hit, file, recent project)
⌘→ (editor) Pass the current selection to the agent
⌘M Cycle Actual · Original · Diff · Split
⌘C / ⌘↵ / ⌘P (git) Focus commit message / commit staged / push branch
⌘A Toggle auto-fit panels (columns re-fit on resize and focus)
⌘. Toggle hidden dotfiles in tree and search
⌘G Show or hide the source-control column
⌘S / ⌘W / ⌘D Save / close / delete (confirm) the current file
⌘N Open the project note; it saves on focus loss
⌘P (note open) Send the whole note to the agent
right-click a row Context menu, anchored to the pointer, first item pre-highlighted
esc Close the top overlay, menu or prompt; never more than one

Rules that hold everywhere:

  • Exactly one overlay at a time, on a flat ink scrim. Overlays never stack.
  • Hover changes fill one step and nothing else. No lift, no scale, no shadow, no opacity.
  • Press holds the hover colour. Nothing shrinks.
  • Focus is always the 2px amber border plus the 2px 22% ring. Never remove it.
  • Disabled is 40% opacity plus cursor: not-allowed, no recolouring.
  • Empty and error states are one plain sentence starting with an em dash. No icon, no apology, no exclamation mark.

State

  • project — path, branch, recent list (persisted)
  • openFile — path, language, dirty flag, cursor line/col, view mode (actual|original|diff|split)
  • tree — expanded paths, selected path, showHidden
  • git — staged[], unstaged[], commit message draft, ahead/behind counts
  • agent — model, session, transcript, prompt draft, pending tool calls, auth notices
  • overlaynull | search | shortcuts | note | diff | launcher | menu | passOn
  • panels — column widths, autoFit, gitVisible
  • note — text, dirty flag (write on blur)

Search runs per keystroke against three indexes (open file, project contents, file names) and reports counts per column; a query with no hits leaves the columns in their empty state rather than collapsing them.

Assets

None. No images, no illustrations, no photography. Icons come from Lucide (lucide@0.544.0, stroke width 1.75); the Unicode glyphs in the mock are placeholders. Fonts are IBM Plex Mono and IBM Plex Sans (currently from Google Fonts — swap in local woff2 for a desktop build).

Files

  • Helder IDE.dc.html — the design board: all screens, one canvas, real sizes
  • tokens/*.css — the Kade token files the board is built on (colour, type, spacing, radius, elevation, motion, fonts)
  • styles.css — the token entry point

Open Helder IDE.dc.html in a browser; the board is inert (no interaction) by design.