Batch 0

Foundations

Ten decisions that constrain everything after them. Colour, wire semantics, type, rhythm, surface craft, motion, icons, focus and the copy layer. Every later batch composes from these and adds no new raw values.

F-01 · F-06

Colour and surfaces

A near-neutral interface so the circuit can be the only colourful thing on screen. Contrast is stated for every ink against the worst-case background.

Surfaces

app

#f5f7f8

Page background behind every panel

surface

#ffffff

Cards, panels, topbar

surface-sunken

#eef1f4

Circuit canvas, dock, inset wells

surface-hover

#f7f9fa

Row and ghost-button hover

surface-active

#eaeff3

Pressed state on quiet controls

surface-inverse

#111827

Tooltips, mono overlays on the canvas

Three depths only. Sunken carries the canvas and the device dock; raised is surface plus elevation, never a different colour.

Ink

ink

#11182716.5:1 AAA

Headings and primary body text

ink-secondary

#5b65765.5:1 AA

Supporting copy, descriptions

ink-tertiary

#6670854.6:1 AA

Metadata, evidence lines, timestamps

ink-disabled

#94a2b12.4:1 non-text

Non-text only: disabled glyphs, empty-state art

Measured against app background #F5F7F8 — the worst case in the product. Every ink that carries a word clears WCAG AA at 12px; ink-disabled is deliberately below it and is never allowed to hold text.

Lines

border

#e4e9ed

Hairline on cards, panels, inputs

border-strong

#cfd8e0

Dividers that must survive a busy canvas

grid

#dce3e8

Technical dot grid behind the circuit

Primary accent

accent

#1677ff

Primary buttons, active state

accent-hover

#0e63e0

Hover

accent-active

#0a53bd

Pressed

accent-soft

#eaf3ff

Selected row, active tab wash

accent-border

#b9d8ff

Inner layer on active surfaces

Electric blue is the agent's colour: actions it offers, tools it registers, targets it points at.

Secondary accent

teal

#14b8a6

Target rings, expected routes

teal-hover

#0f9e8e

Hover

teal-soft

#e6f7f5

Expected-state background

teal-border

#9ee4dc

Expected-state edge

Teal always means expected — the correct pin, the reference view, the position the servo should reach.

Status

success

#16a36a

Step verified, test passed

warning

#f59e0b

Recoverable finding

error

#e5484d

Failed test, blocking mismatch

success-soft

#e7f6ef

Passed row background

warning-soft

#fef4e6

Finding card background

error-soft

#fdecec

Failed row background

Each status is always paired with an icon and a word. Colour never carries the meaning alone.

Surface stack in context

app

surface

surface-sunken · canvas well

surface + elevation e2 · a floating panel over the canvas

The whole product is built from these four layers. Anything that looks like a fifth layer is elevation, not a new colour.

F-02

Semantic wire palette

Seven wire roles, each with a colour, an icon and a word. A cable is solid and plugged in at both ends; a dash means nothing is physically there. This is the only palette allowed to be saturated.

Roles

Semantic wire roles
SampleLabelMeaningStrokeToken
5VPower3px · solid + rim#e0393e
GNDGround3px · solid + rim#3a4450
Signal ADigital signal3px · solid + rim#d99114
Signal BSecond digital signal3px · solid + rim#2d7ff9
Servo signalPosition signal to the servo3px · solid + rim#f5850f
Servo GNDGround, on the servo's brown lead3px · solid + rim#8b4a1d
MismatchConnected to the wrong point3.5px · solid + rim#f0742a
ExpectedWhere this wire belongs2.5px · dash 3 4#0fa98f
Not wiredNothing connected yet2px · dash 2 5#a9b4c0

A cable is always solid, however badly it is connected — a dash means there is nothing physically there. So a mismatch is never told by the stroke: the wire keeps its colour while every other one drains to grey, and the callout and pin marks say the rest.

Desaturated check

5V
GND
Signal A
Signal B
Servo signal
Servo GND
Mismatch
Expected
Not wired

The same specimens with all colour removed. Cables stay separable from annotations — solid with a plug on each end against a bare dashed line — and power stays separable from ground by weight. Which cable is wrong is not a stroke property and never was: it is carried by the callout, the two pin marks, and the grey every other wire falls to.

F-03

Typography

Geist for the interface, IBM Plex Mono for anything the hardware reports or the sketch defines.

Geist — interface

display

30 / 36 · -0.021em · 600

Completion screen headline. Used once per screen at most.

Your build is working

h1

24 / 30 · -0.017em · 600

Dashboard and project detail headings.

Build real electronics with an agent beside you.

h2

19 / 26 · -0.012em · 600

Section headings, modal titles, project card titles.

Smart Parking Barrier

h3

15 / 22 · -0.006em · 600

Panel headers, finding titles, step names.

Connection mismatch

body-lg

16 / 24

Lead paragraph under a heading. Never inside dense panels.

Follow a real project, recover from wiring mistakes, and understand why every connection matters.

body

14 / 21

Default. Instructions, explanations, card copy.

Echo measures how long the reflected pulse takes to return.

body-sm

13 / 19

Dense panels: step rail, findings list, activity timeline.

Agent inspected wiring for Step 3

caption

12 / 16 · 500

Metadata under a title. Evidence lines, timestamps.

Camera frame · 94% confidence

overline

11 / 14 · +0.06em · 600 · uppercase

Group labels above lists. Sparingly.

Components in this step

Headings stop at 30px. This is a working tool: a headline that fills the viewport would push the actual product below the fold.

IBM Plex Mono — technical values

mono-lg

15 / 22

Live telemetry readout in the device dock.

Distance: 18 cm

mono

13 / 18

Serial monitor lines, tool names, pin references.

verify_current_step → passed in 240 ms

mono-sm

11 / 15 · +0.02em

Inline technical values inside body copy: D7, 5V, 94%.

D6 → D7 · 5V · GND

Anything the board reports or the sketch defines renders in mono with tabular figures, so a changing distance readout never shifts its neighbours.

Mixed in context

Wire the distance sensor

Connect the sensor's Echo pin to digital pin D7. Echo measures how long the reflected pulse takes to return.

Camera frame · 94% confidence

The pairing exists so a pin reference is recognisable mid-sentence without bold, colour or quotes.

F-04

Layout rhythm

A 4px scale for everything inside a panel, and fixed frames for the workbench's four zones.

4px scale

  • 0.52pxIcon optical nudges only
  • 14pxIcon-to-label gap in dense chips
  • 1.56pxIcon-to-label gap in buttons
  • 28pxInside chips, badges, tight rows
  • 2.510pxList row padding
  • 312pxCard padding (dense), panel row gap
  • 416pxCard padding (default), panel padding
  • 520pxCard padding (roomy), section gap
  • 624pxBetween cards in a grid
  • 832pxBetween sections on a page
  • 1248pxBetween major page regions

Everything in the product snaps to this scale. Values above 48px only appear as page-level separation, never inside a panel.

Fixed frames

topbar
64px
Workbench control bar height
rail
252px
Left step panel width
agent
360px
Right agent workspace
dock
44px
Device dock, collapsed
dock-open
224px
Device dock, expanded
shell
1360px
Max content width off-workbench

The workbench is a four-zone instrument panel, so its regions are fixed rather than fluid. Only the canvas absorbs the remaining width.

Workbench frame at 1440×900

Top control barh 64
Step railw 252
Circuit canvasfluid
Agent workspacew 360
Device dockh 44 / 224

Scaled proxy of Batch 7's four-zone layout, drawn from the same tokens. The canvas keeps 764px at 1440 and 604px at 1280 — enough for the board, breadboard and servo without scrolling.

Breakpoints

WidthBehaviour
≥ 1440Target layout. All four zones visible, dock expandable.
1280–1439Same structure, canvas absorbs the difference. No horizontal scroll.
1120–1279Agent workspace becomes a drawer over the canvas.
< 1120Stacked flow: instruction, canvas, steps, findings. Small-screen notice shown, nothing hidden.
F-05

Radius and elevation

Restrained corners, three shadow levels, and inner layers instead of colour swaps for active states.

Radius

xs4px

Inline code, focus ring

sm6px

Badges, chips, pills

md10px

List rows, small wells

lg12px

Cards, findings, stages

xl14px

Fields, panels, dock, modals

2xl18px

Full-bleed feature block

full

Every button, badge, chip and segment

Surfaces sit at 10–14px. Interactive controls — buttons, badges, chips, segments — are full capsules, so shape alone separates “something to press” from “something to read”.

Elevation

e1

Resting cards. Barely there — the border does the work.

e2

Hovered cards, floating canvas controls.

e3

Popovers, dropdowns, modals. The only real lift in the product.

Three levels, all cool-grey and low-opacity. No glow, no coloured shadow except under the primary button.

Inner layers

Resting row

border + e1

Default

Active row

accent-soft + layer-active

Selected step, active tab

Sunken well

sunken + layer-sunken

Canvas, serial monitor

Active states add a second layer inside the surface instead of changing its colour wholesale. This keeps a selected row readable when it sits next to a coloured wire.

Raised primary

Verify stepShow meCheck this

Static specimens — the live capsule buttons are in Batch 1.

The primary action lifts off the surface with a tinted shadow rather than a gradient — the one place the product allows a coloured shadow. Buttons are capsules (direction A).

F-07

Motion

Motion confirms that something happened. Four durations, three curves, five named behaviours, and a full collapse under reduced motion.

Preference

prefers-reduced-motion: no-preference

Full motion vocabulary active.

Every animated component reads this. When reduced motion is on, states still change — they just change immediately.

Durations

  • instant150msHover, focus, colour change
  • quick220msTooltip, chip, finding card enter
  • settle280msTab switch, step content swap, dock
  • deliberate350msCanvas highlight, servo preview, guidance arrow

150–350ms. Nothing in the product animates longer than the time it takes to read the label that changed.

Easing

out-soft

cubic-bezier(0.16, 0.84, 0.44, 1)

Default. Anything entering or settling.

in-out-soft

cubic-bezier(0.4, 0, 0.2, 1)

Symmetric moves: pan, dock open and close.

overshoot

cubic-bezier(0.34, 1.26, 0.64, 1)

Success confirmation only. One small bounce, never decorative.

Motion vocabulary

cp-pulse-ring

Agent is connected and listening. The only infinite loop allowed.

cp-trace

Light travelling along the wire the agent is talking about.

cp-attention

Error ring around a wrong pin. Fades, never flashes.

cp-sweep

A test stage is running with no known duration.

Five behaviours, defined once as keyframes. Components compose them; they never invent new ones.

F-08

Icon system

Lucide at 1.75 stroke weight, four sizes, and a small working vocabulary.

Stroke weight

2.0 — heavy

1.75 — product standard

1.5 — too faint at 14px

Lucide ships at stroke-width 2. Against Geist at 13–14px that reads heavy and slightly toy-like, so the product standardises on 1.75.

Sizes

Distance

xs14px

Inline with caption and mono-sm

Distance

sm16px

Buttons, list rows, tabs — default

Distance

md18px

Panel headers, toolbar actions

Distance

lg20px

Empty states, feature blocks

Icons sit on the text baseline with a 6px gap and never shrink below 14px. Icon-only controls always carry an aria-label.

Working set

Navigation & shell

ArrowLeft

Search

SlidersHorizontal

ChevronDown

Settings2

RotateCcw

Status

Check

TriangleAlert

CircleAlert

Activity

Play

Canvas

ZoomIn

ZoomOut

Maximize

Layers

Crosshair

Eye

Build domain

CircuitBoard

Cpu

Gauge

Lightbulb

Plug

Wrench

ListChecks

Terminal

Sparkles

A deliberately small vocabulary. New icons get added only when an existing one would mislead.

F-09

Focus

One visible ring on every interactive element, and hit areas that stay reachable in dense panels.

One ring

Why D7?

Press Tab through this row. Every interactive element in the product uses the same 2px accent ring at 2px offset — no per-component variation, no ring suppressed for aesthetics.

On coloured ground

outline-color switches to white; width and offset stay identical.

The ring keeps a white inner halo when it lands on an accent or status surface, so it never disappears into its own background.

Hit area

40×40

44 tall

Minimum 40px for dense panel controls, 44px for anything primary. Small glyphs get padding, not a smaller target.

F-10

Content layer

Brand and copy live in data, not in components — the working name can change without touching a screen.

Brand record

brand.namePilotCircuits
brand.agentNameBuild Coach
brand.protocolWebMCP
brand.originhttps://pilotcircuits.com

Rename the product by editing one object. Nothing downstream hardcodes the name.

Copy namespaces

copy.labcopy.wirecopy.brandcopy.navcopy.dashboardcopy.landingcopy.projectscopy.componentscopy.conceptscopy.librarycopy.statuscopy.projectDetailcopy.buildcopy.briefingcopy.workbenchcopy.democopy.agentPanelcopy.findingscopy.coachcopy.workspacecopy.devicecopy.testcopy.inspectioncopy.completecopy.a11y

Screens import one namespace each. Strings that appear in more than one place — status labels, agent actions — live in a shared group so they can never drift.

Voice

Good

“Echo is connected to D6. This build expects D7.”

Avoid

“Oops! Something went wrong with your wiring! 😅”

Good

“Demo feed · Simulated UNO-compatible board”

The interface always says when it is showing simulated data.

Short, factual, second person. The product states what it observed and what it expects; it never congratulates the user for existing, and never claims a capability it does not have.