docs GitHub

Contributing

Design tokens

Direction: Instrument, reduced. Mark: Lead (one wire bent into a v, with the signal dot leaving its end). Take values from the palette, never retype them. Do not add colours. Artboards: project/IdMarks, IdSystem, IdVoice.

Colour: dark (default)

The palette lives in core/config/theme.js, and these tables are drawn from it. The Deck paints the same values (a test holds deck/css/deck.css to them). To change a colour on your box, set it under theme.colors in ~/.vyre/config.json, for example "theme": { "colors": { "dark": { "signal": "#B8E65A" } } }, and reload the Deck: the box serves your overrides as /theme.css. A value that is not a plain CSS colour is ignored.

SwatchTokenValueUse
--graphite#0E0D0CPage ground. Warm graphite black.
--carbon#161513Panels, windows, app-icon tile. One step up from ground.
--raised#1E1C1AHover rows, popovers, tab strips. Use rarely.
--rule#2B2926Hairline rules and dividers (1px). The default separator.
--rule-strong#3A3733Input borders, swatch outlines, vertical rules in lockups.
--ash#8C877DEngraved labels, captions, placeholders. 5.4:1 on graphite. Smallest text colour allowed.
--stone#B3AEA4Secondary text. 9:1 on graphite.
--bone#F1EEE6Primary text, the wire in the mark.
--signal#F1EEE6Focus and the one primary action per view. The mark's dot. Never decoration, never a large fill.
--signal-hover#FFFFFFHover on signal-filled buttons.
--signal-ink#0E0D0CText on a signal fill.
--signal-washrgba(241,238,230,0.12)Selected row, focus ring fill.
--beacon#B8A4FFNeeds you. Held tool calls, approvals, the menu-bar dot. Nothing else.
--beacon-badge-ink#0E0D0CThe count on a beacon dot badge.
--code-bg#121110Behind code and command output.

Errors are not coral. A failed run is Bone text with an Ash failed label; if it needs the user's action, it becomes Beacon.

Colour: light (paper)

Paper swaps the roles the views use, so its names are roles (bg, text, focus), and these are the keys for theme.colors.light.

SwatchTokenValueUse
--bg#F4F1EAGround (paper).
--panel#FBFAF6Panels (paper raised).
--hover#EEEAE2Hover rows.
--rule#DCD7CCHairlines.
--rule-strong#C9C3B7Input borders.
--text#141311Primary text and the mark (ink).
--text-2#4A463FSecondary text.
--label#6B665DLabels. 5.0:1 on paper.
--primary-bg#141311Primary buttons: ink fill with paper text.
--primary-hover#4A463FHover on a primary button.
--primary-ink#F4F1EAText on a primary button.
--focus#141311Signal on paper: focus rings and primary text links.
--signal-washrgba(20,19,17,0.10)Selected row, focus ring fill.
--beacon-ink#5B3FC4Beacon on paper, for text.
--beacon-dot#5B3FC4Beacon on paper, for the dot graphic.
--beacon-badge-ink#F4F1EAThe count on a beacon dot badge.
--code-bg#F0EDE5Behind code and command output.

On paper the mark is one colour: ink wire and ink dot.

Type

Google Fonts link (one <link>, in <helmet>):

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600&amp;family=JetBrains+Mono:wght@400;500&amp;display=swap">
  • Sans: 'Instrument Sans', 'Helvetica Neue', Arial, sans-serif (400, 500, 600)
  • Mono: 'JetBrains Mono', ui-monospace, Menlo, monospace (400, 500)

Kept both. Instrument Sans has narrow, slightly drawn terminals that sit well beside the monoline wordmark; JetBrains Mono renders terminal output in Glass and the CLI at 12-13px better than any other free mono.

RoleFamilySize / lineWeightTracking
DisplaySans72 / 76600-0.035em
H1Sans44 / 48600-0.03em
H2Sans28 / 34600-0.02em
H3Sans20 / 26600-0.01em
BodySans15 / 224000
SmallSans13 / 184000
Label (engraved)Mono11 / 14500, UPPERCASE+0.16em, colour --ash
Code / logMono13 / 204000
Hero commandMono60-76 / 1.12500-0.03em

Buttons: Mono 12/16, 500, uppercase, +0.12em.

Shape

TokenValueUse
--r-00Rules, table rows
--r-14pxChips, keycaps, swatches
--r-26pxButtons, inputs
--r-310pxPanels, Capsule
--r-414pxWindows (Glass, Deck frames)
App iconrx = 22.46% (230 of 1024)

Spacing: 4px base. Use 8, 12, 16, 24, 32, 48, 72. Page side gutter 72px desktop, 16px phone.

Lines and light

  • Hairline: 1px solid #2B2926. Separate with rules, not nested boxes. A box inside a box is a bug.
  • Strong: 1px solid #3A3733.
  • Primary: Bone (30 Sep 2026, user's pick): no accent hue. Dark: cream #F1EEE6 fill, #0E0D0C ink, hover #FFFFFF. Paper: ink #141311 fill, #F4F1EA ink. Focus, washes and the mark dot use the same neutral. On Deep glass a chip has no wash and focus is two-tone (see chip.md). A repo test fails if the retired accent returns.
  • Focus: outline: 2px solid #F1EEE6; outline-offset: 2px; (paper: #141311).
  • Light drawn once (top edge only, on windows and the Capsule): box-shadow: inset 0 1px 0 rgba(241,238,230,0.06), 0 24px 48px -24px rgba(0,0,0,0.6);
  • Popover: box-shadow: inset 0 1px 0 rgba(241,238,230,0.05), 0 12px 24px -12px rgba(0,0,0,0.55);
  • No gradients, glows or blur behind content. No animated backgrounds.

Mark: Lead

Construction (24 grid): V apex (12, 19.5), arms to (3.5, 5.5) and (20.5, 5.5), stroke 2.4, round caps and joins. The right arm stops 4.9 units short of its end; the dot (r 2.3) sits at the end. Clearspace: two dot diameters on every side. Minimum size 16px (use the favicon drawing below 20px). Never rotate, outline, or colour the wire anything but Bone or Ink. The dot is Signal on dark, Ink on paper, Beacon only for "needs you".

24px (paste verbatim)

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M3.5 5.5L12 19.5L17.96 9.69" stroke="#F1EEE6" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/><circle cx="20.5" cy="5.5" r="2.3" fill="#F1EEE6"/></svg>

Paper version: replace both colours with #141311.

18px menu bar, idle (template: monochrome)

<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true"><path d="M2.8 4.6L9 14.8L13.23 7.85" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><circle cx="15.2" cy="4.6" r="1.9" fill="currentColor"/></svg>

18px menu bar, needs you

The dot grows slightly and turns Beacon. Ship as a non-template image (#B8A4FF on dark bars, #5B3FC4 on light bars).

<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true"><path d="M2.8 4.6L9 14.8L13.23 7.85" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><circle cx="15.2" cy="4.6" r="2.3" fill="#B8A4FF"/></svg>

16px inline (no tile)

<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M2.5 4L8 13L11.52 7.24" stroke="#F1EEE6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="13.5" cy="4" r="1.8" fill="#F1EEE6"/></svg>

Favicon (16 and 32; tile)

<svg width="32" height="32" viewBox="0 0 32 32" fill="none" aria-hidden="true"><rect width="32" height="32" rx="7" fill="#161513"/><path d="M8 10L15.5 22.5L19.81 15.31" stroke="#F1EEE6" stroke-width="3.2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="23" cy="10" r="3" fill="#F1EEE6"/></svg>

App icon (1024; also use for 64+)

<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" aria-hidden="true"><rect width="1024" height="1024" rx="230" fill="#161513"/><rect x="2" y="2" width="1020" height="1020" rx="228" stroke="#F1EEE6" stroke-opacity="0.08" stroke-width="4"/><path d="M230 3H794" stroke="#F1EEE6" stroke-opacity="0.2" stroke-width="3"/><g transform="translate(512 512) scale(25) translate(-12.55 -11.95)"><path d="M3.5 5.5L12 19.5L17.96 9.69" stroke="#F1EEE6" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/><circle cx="20.5" cy="5.5" r="2.3" fill="#F1EEE6"/></g></svg>

Wordmark "vyre" (monoline, drawn in the mark's wire; always lowercase)

Set height; width follows (ratio 62:26). At 40px tall it is 95px wide.

<svg width="95" height="40" viewBox="-2 3 62 26" fill="none" role="img" aria-label="vyre"><path d="M0 6L6 20L12 6M16 6L22 20M28 6L19.4 26M33 6V20M33 13Q33 6 40 6M43 13H57A7 7 0 1 0 55.36 17.5" stroke="#F1EEE6" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>

Lockups

[mark 36] 16px gap [wordmark h40] 16px gap [1px x 28px rule #3A3733] 16px gap [MONO 16/20 500 UPPERCASE +0.18em #B3AEA4: AGENT | PLATFORM | AI]

In nav bars: mark 20 + wordmark h22, no product label.

Voice

Short, plain, first person only when Vyre is reporting what it did. Name the fact, then stop. No "unleash", "supercharge", "AI-powered", "seamless", no exclamation marks.

  • Your agent has its own computer. Watch it work, or take the wheel.
  • From your notes in March. No model was used. (Recall)
  • This deletes 214 files. I stopped before running it. (Beacon)
  • You have control. Hand it back when you're done. (Glass take-over)
  • Only your tailnet can open this address.
  • Install: npm install -g vyre. One command, shown alone, never behind OS tabs.