OpenAct / design

The OpenAct design system

The Promptbook. Your agent reads it first.

The Promptbook holds the tokens, the rules and the checks for OpenAct apps. It is one file. App developers read it. Their coding agents read it before they build a screen.

v1.0.0 · 15 cues · 60 tokens

Paste this into your coding agent

Claude Code · Codex

You build an app for OpenAct. Before you write UI code, read the OpenAct Promptbook at https://openact.ing/design/promptbook.md and AGENTS.md.

- Pick colors by intent from the Promptbook tokens. Never write a hex value.
- Build screens from the blocking patterns and the @openact/ui components.
- Show agent work with the AgentState component and its five states.
- Write all text in ASD-STE100 style: short sentences, active voice.
- If the app needs an accent, run: npm run design -- seed <app-id> <hue>
- Before you finish, run: npm run design -- check, then npm test.
- In the pull request, list the cues that need a review by a person.
Click the prompt once to select all of it.

Why a promptbook?

In a theater, the prompt book is the stage manager's master copy of the show. It holds the script, every cue and every move. The crew works from it. Today, much of the crew that builds software is coding agents. They need the same master copy.

Written for agents first

The source is a JSON file and a Markdown file, not a picture. An agent can read every rule. So can a person.

Intent, not values

Pick a token by what it means. Use status-done for a done task. Never pick a green because it looks good.

Seeds, not palettes

A new app gives one hue. A script makes the light and dark values and tests their contrast.

Agents have states

Agent work has five states with their own tokens. A person can always see what the agent does.

Every rule has a check

A rule is a cue. Each cue has a script, a test or a review by a person.

The system under every OpenAct app.

Seven parts. Each part lives in the code, and this page draws itself with the same token values.

Tokens

Say what it means. The value follows.

An agent asks for an intent. The theme gives the right value for light or dark.

a task is donetext-status-done
the agent needs youtext-agent-wait
a date or a counttext-muted-foreground
this deletes datavariant="destructive"

Components

shadcn/ui inside. Your app outside.

Every app builds from the same kit in @openact/ui. Icons come from Lucide through one Icon component.

Agent states

Agent work has its own signs.

Every agent surface uses five states. People learn one set of signs. The agent never goes past the wait state on its own, and agent work never uses the brand colors.

Reading 12 tasks in Spring season launchthink
Moving 3 tasks to Reviewact
Waiting for your approvalwait
Moved 3 tasks to Reviewdone
You rejected the change. Nothing was deleted.fail

Motion

Three curves. Leave faster.

Enter, leave and move. Every animation stops for reduced motion.

ease-enter · 200 msease-move · reorder and dragease-exit · 120 ms, dashed

Contrast

Checked by a script.

Every text pair needs 4.5:1 in both themes. The lower of the two themes shows here.

  • foreground / background19.0:1 AAA
  • muted-foreground / background5.2:1 AA
  • destructive / card4.8:1 AA
  • agent-act / card5.9:1 AA
  • agent-wait / card6.1:1 AA
  • s-doing / card3.4:1 3:1 ok

Ship

A failed cue is a fix in a diff.

This check failed while we wrote the Promptbook. Our first wait color was too close to the brand gold. The fix was one line.

C09 --agent-wait is too close to --brand-gold in dark (0.021). Agent states must not look like the brand.
196---agent-wait: #f0b45a;
196+--agent-wait: #cf9cff;
Promptbook: every script cue passes.

Board

Items that move through stages.

List and detail

A list and the open item.

Document

Long text on a page.

Form

Settings and new items.

Agent panel

The agent beside the work.

Make a design system for your app in six steps.

Use this method when you start an OpenAct app with a coding agent. The person decides. The agent does the work and runs the checks.

StepThe personThe agent
01ScriptWrites the premiseOne sentence about who uses the app and what they do.Reads the PromptbookPicks the blocking pattern for each screen.
02CastPicks one hueOnly if the app needs its own accent.Runs the seednpm run design -- seed <app-id> <hue>, then pastes the tokens into theme.css.
03BlockApproves the screensA short list, one pattern per screen.Builds the screensFrom the pattern and the @openact/ui components.
04CueNames the risky actionsSays which agent actions need approval.Writes the states and textAgentState for agent work. ASD-STE100 for every sentence.
05RehearseLooks at every screenLight and dark, on a phone and a desktop.Runs the checksnpm run design -- check and npm test. Fixes every problem.
06OpenReviews and mergesChecks the cues marked review.Opens the pull requestLists the cues that need a person.

Step 02 in practice

One hue in. Two safe values out.

Most apps need no accent. When an app needs one, give the script a hue from 0 to 360. It finds a light and a dark value with 4.6:1 or more on the page and on cards. It also picks the text color for buttons in that accent.

light · #0e8557Book a consult
dark · #23c987Book a consult
$ npm run design -- seed advisory 160

/* In :root */
  --app-advisory-accent: #0e8557; /* 4.65:1 on page and card */
  --app-advisory-accent-foreground: #ffffff; /* 4.65:1 on the accent */

/* In .dark */
  --app-advisory-accent: #23c987; /* 8.34:1 on page and card */
  --app-advisory-accent-foreground: #0d0f14; /* 8.92:1 on the accent */

/* In @theme inline */
  --color-app-advisory-accent: var(--app-advisory-accent);
  --color-app-advisory-accent-foreground: var(--app-advisory-accent-foreground);

Fifteen cues. Each one has a check.

A script checks some cues with every npm test. A test covers one. A person checks the rest in the pull request.

CueRuleCheck
C01Use theme tokens for every color. Do not write hex, rgb or oklch values or fixed Tailwind palette classes in components.script
C02Give every token a light value and a dark value.script
C03Text has a contrast of 4.5:1 or more on its surface, in both themes.script
C04Status marks, icons and lines that carry meaning have a contrast of 3:1 or more.script
C05Pick a token by its intent. Do not pick a token by its color.review
C06Use one primary action on a screen.review
C07Every signed-in page starts with SiteHeader and puts its content in PageBody.review
C08Build from the shadcn/ui components in @openact/ui. Use Lucide icons through Icon.review
C09Show agent work with the five agent states and the AgentState component. Never show agent work in the brand colors.script
C10An agent change that deletes data or changes people waits for a person. Show Approve and Reject.test
C11Use the motion tokens. Stop every animation when the person asks for reduced motion.review
C12Write text in ASD-STE100 style: short sentences, active voice, one idea per sentence, American spelling.review
C13Do not use em dashes in text.script
C14Start the name of an app token with the app id, such as --app-docs-accent.script
C15Look at every new screen in light and dark, on a phone and on a desktop, before you open a pull request.review

The tokens, by intent.

The build reads these values from theme.css. Stage surfaces and identity colors are in promptbook.json.

ClassIntentLightDark
agentThe five states of agent work. They never use the brand colors.
agent-thinkThe agent reads and plans.#5d6675#a3adbb
agent-actThe agent runs a tool.#2f5bd3#8aabff
agent-waitThe agent needs a person to approve or reject.#8a35c9#cf9cff
agent-doneThe agent finished the step.#1b7a4b#56c98f
agent-failThe step failed or a person rejected it.#c0392b#f37b63
meaningColors that carry meaning. Never use them for decoration.
status-backlogStatus: not planned yet.#8d99a9#7c899d
status-todoStatus: planned.#4a78c7#6c9ae9
status-doingStatus: in progress.#c47b10#e8a138
status-reviewStatus: waiting for review.#8658c4#a886e6
status-doneStatus: done.#2c9662#4abc82
priority-highPriority: high.#c0402b#f37b63
priority-medPriority: medium.#a8711a#e1aa4c
priority-lowPriority: low.#737373#a3a3a3
liveSomething changes now, such as another viewer on the page.#2c9662#4abc82
todayThe line for today on a timeline.#d53f2c#fe6a54
warnThe fill of a warning.oklch(0.97 0.04 85)oklch(0.27 0.04 75)
warn-foregroundThe text of a warning.oklch(0.42 0.09 70)oklch(0.86 0.1 85)
warn-borderThe edge of a warning.oklch(0.86 0.09 85)oklch(0.42 0.07 75)
brandThe OpenAct identity: Playbill ink with a stage gold cue.
brandThe ink of the OpenAct mark.#1c1824#ece7f2
brand-foregroundText on the brand ink.#ffffff#1c1824
brand-goldThe cue light. Use it for brand moments only, never for status.#8a6420#e3b85c
actionThings a person can do.
primaryThe main action on a screen. Use one per screen.oklch(0.205 0 0)oklch(0.922 0 0)
primary-foregroundText on the main action.oklch(0.985 0 0)oklch(0.205 0 0)
secondaryOther actions.oklch(0.97 0 0)oklch(0.269 0 0)
secondary-foregroundText on other actions.oklch(0.205 0 0)oklch(0.985 0 0)
accentHover and selected states.oklch(0.97 0 0)oklch(0.269 0 0)
accent-foregroundText on a hover or selected state.oklch(0.205 0 0)oklch(0.985 0 0)
destructiveAn action that deletes or cannot be undone.oklch(0.577 0.245 27.325)oklch(0.704 0.191 22.216)
destructive-foregroundText on a destructive fill.#ffffff#ffffff
surfaceThe planes that content sits on.
backgroundThe page.oklch(1 0 0)oklch(0.145 0 0)
foregroundText on the page.oklch(0.145 0 0)oklch(0.985 0 0)
cardA raised panel, such as a task card or a dialog.oklch(1 0 0)oklch(0.205 0 0)
card-foregroundText on a card.oklch(0.145 0 0)oklch(0.985 0 0)
popoverA menu or a popover.oklch(1 0 0)oklch(0.205 0 0)
popover-foregroundText in a menu.oklch(0.145 0 0)oklch(0.985 0 0)
mutedA quiet fill, such as a hover row or a code chip.oklch(0.97 0 0)oklch(0.269 0 0)
muted-foregroundSecondary text: dates, help text, counts.oklch(0.535 0 0)oklch(0.708 0 0)
borderLines between parts.oklch(0.922 0 0)oklch(1 0 0 / 10%)
inputThe edge of a form field.oklch(0.922 0 0)oklch(1 0 0 / 15%)
ringThe focus ring.oklch(0.708 0 0)oklch(0.556 0 0)
scrimThe shade behind a dialog or a sheet.oklch(0 0 0 / 50%)oklch(0 0 0 / 65%)

Build your first OpenAct app.

Start from the repository. Give your agent the prompt at the top of this page. Keep the person in charge of every cue marked review.

  1. git clone github.com/marketgrowth/openact
  2. Give your agent the prompt. Name your app and its users.
  3. npm run design -- check and npm test
  4. Open a pull request. A person approves it.