EDITOR.md is the source of truth and src/generated/editor.ts is built from it, so the document describing the editor's palette and the code applying it cannot disagree. The postbuild step emits the stylesheet the overlay ships.
11 KiB
name, description, tokens
| name | description | tokens | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Airship Editor | Airship's visual-editor token system — a dark editor palette: dense neutral surfaces, hairline borders, a single Blue #0D99FF selection voltage, and a restrained 3–5% luminance surface progression. This front-matter is the canonical token source for the editor chrome (`@airship/editor-tokens`, emitted under the `--ap-*` namespace). It is fully independent of the `--pk-*` marketing tokens in home/packages/tokens and their re-skinned sibling in examples/vite-react, and evolves separately. No shadows on panels — separate surfaces with borders instead. |
|
Airship Editor Tokens
The visual editor's design system — a dark editor palette. The
@airship/editor-tokens package generates its TypeScript token objects and CSS
custom properties (--ap-*) directly from this front-matter, so this file and
the code never drift. This system is independent of the --pk-* marketing
tokens in home/packages/tokens; the two evolve separately.
There are in fact two --pk-* sets in this repo — home/packages/tokens and
examples/vite-react/packages/tokens, which run an identical pipeline against
different specs. They never collide with each other or with this one: each lives
in its own pnpm workspace serving its own app, and pnpm scopes package names per
workspace.
Character
-
Neutral grays, not warm — surfaces step
#1E1E1E → #454545in ~3–5% luminance increments ({surface.canvas}→{surface.selected}). This progression is the core of the editor's feel: calm, dense, cohesive. -
Hairline borders, no heavy shadows. Panels separate with
{border.*}hairlines; shadows are reserved for the floated chrome ({shadow.*}). -
A single accent: Blue
{primary.primary}#0D99FF. It carries selection, focus, links, and the primary action — used scarcely. -
{semantic.*}is for state, and state only — success, warning, error. There used to be a purple and an orange family here too, and having them is what made them get used: purple ended up on a@mediacondition and on the word "Thinking", neither of which is a state. Hue in a grey editor is a claim that something needs attention, so a colour with no state behind it spends that attention on nothing. Anything that is merely a different kind of thing is said with weight, italics or the{text.*}ramp instead. -
Dedicated
{text.*},{icon.*},{border.*},{blue.*}and `{gray.*}" scales keep surfaces, typography and icons decoupled from each other. -
Icons sit one step below text.
{icon.secondary}is the resting colour for every glyph;{icon.primary}is reserved for hover and the active state of a segmented control. An icon that matches the text colour reads as loud as a label, which is what makes a dense panel feel busy. -
Type is a six-step ramp,
{fontSize.micro}9px →{fontSize.heading}14px. The editor is deliberately denser than the marketing site:label(12px) is the workhorse for controls,body(11px) for monospace metadata, andheading(14px) is as large as chrome ever gets. -
Icons render at
{iconSize.*}— 16/20/24/28. The imported glyph set insets its artwork inside a 24 box (the mark spans roughly 4..20), so 24px is the default, not 16: a 24-box glyph drawn at 16px yields a ~10px mark. -
{control.height}24px and{control.gutter}8px define the inspector's rhythm — every field, icon button and segmented cell is one control tall. -
{control.icon-box}28px is the chrome's ghost icon button — the bottom bar's tools, the canvas verbs beside them, the dock headers, Send. Larger thancontrol.heighton purpose: those buttons carry a 20px glyph and nothing else, so at 24 the mark would sit flush against the button's edge with no optical padding at all, which is what the dock headers used to do while the bottom bar a few pixels away did not. Inspector controls stay oncontrol.height; they sit in a field grid whose rhythm is the thing that matters there. -
Vertical spacing is a three-step scale, not one gap. A panel that puts everything at the same pitch reads as an undifferentiated stack however good its individual controls are, which is exactly what the inspector did before these existed:
Token Separates {control.field-gap}2px parts of one control — the four padding sides, a swatch and its hex, the cells of a segmented group {control.row-gap}6px rows within a group {control.group-gap}12px groups within a section {control.gutter}8px columns on one row These are deliberately off the
{spacing.*}scale. That scale is for page and panel chrome, where 4px is the smallest meaningful step; this one is for the inside of a 24px-tall control, where 2px is a real distance. Two scales, two jobs — and every gap inside the inspector must come from one of these four, so that changing the panel's density is one edit here rather than a sweep through twenty CSS rules. -
{boxModel.*}are conventions, not choices. Blue inside the border, amber outside it, pink between children — the same three every browser's element inspector has used for fifteen years. Anyone who has opened one already knows which is which, and a prettier assignment would cost that recognition for nothing. They are their own group rather than borrowed from{semantic.*}because none of them is a state, and rather than from{primary.*}because only one of them is the accent. -
Motion is three durations and three curves, and no more. Before
{motion.*}existed the overlay had twenty-odd hand-writtentransitiondeclarations and not onecubic-bezieranywhere, which is why nothing in it moved with a recognisable hand.Token Used for {motion.dur-micro}100ms a control changing state under the pointer — background, colour, a caret {motion.dur-base}150ms structure moving — a panel opening, a row stepping aside for a drag {motion.dur-slow}200ms a whole surface re-anchoring, like a dock snapping to the other side {motion.ease}easemicro-states, where the curve is not perceptible and a named one is a lie {motion.ease-out}easeOutQuint the house curve: leaves fast, settles slowly, reads as physical {motion.ease-in-out}easeInOutQuart symmetric moves that start and end at rest Canvas chrome is exempt and must stay exempt. The hover and selection outlines are re-positioned on every pointer move, so a transition on them interpolates between two elements and the outline visibly trails the cursor — it reads as lag, not as easing.
overlay/src/styles/chrome.css.tscarries notransitionat all, and there is a build check that keeps it that way.
Theming
Editor chrome is dark-only. All tokens are emitted flat under --ap-* on the
overlay's scoped root — there is no light/dark swap and no coupling to the
marketing theme.