# An agent skill that draws any object as a blueprint line drawing that inks itself in

Everyday objects in one fine blue line on cream paper, drawn as small building elevations. Ostraca is the open library of them, and each drawing moves through a product's states the way a builder marks a site.

> Can one drawing show a screen as empty, loading, done, changed and broken, if it is marked up the way a builder marks a site?

Status: Building · Disciplines: Design engineering, Product design, Motion · Built with: SVG, JavaScript, React, CSS · Topics: Illustration, Empty states, Agent skills · Year: 2026

Source: https://www.ahmedamr.com/lab/ostraca

*A live prototype runs at this point on the page.*

Most products get their illustrations one screen at a time. A box for the
empty inbox, a cloud with a crack in it for the error, a spinner for
everything in between. Each is its own picture, often from a different pack,
and none of them knows about the others. When a screen goes from loading to
empty to failed, the picture is swapped out from under the reader.

A building site has a mark for each of those moments, and every builder reads
them the same way. Before anything goes up, the job is set out with pegs and
dashed lines. It rises under scaffolding. When it is finished it is signed off.
A change goes on the drawing inside a revision cloud with a numbered triangle.
A wall that has gone wrong is held against a plumb line, and the gap shows how
far off it is.

Those are the states a product screen goes through. The drawings on this site
were already in that hand: blueprint blue, one fine line, a small crew at work
on them. Ostraca turns the hand into a library anyone can use, with 34
figures, the engine that moves them, and a skill that lets a coding agent draw
new ones. It is MIT licensed and has no runtime dependencies. Ostraca are the
limestone flakes Egyptian tomb builders sketched on.

The frame above runs the published package. Pick a figure and a state, and
the line under the drawing is the call that puts it on a page.

## Six states, one set of marks

The code speaks the product's words and the drawing answers in the builder's.

| State | The screen | The drawing |
| --- | --- | --- |
| `idle` | Nothing to report | Built, drawn solid |
| `empty` | Nothing here yet | Set out in dashed lines, its contents faint |
| `loading` | Working on it | Inks in from the ground up, under a ladder or scaffold |
| `success` | Done | The ladder comes away and a tick draws on |
| `changed` | Something new | A revision cloud round one part, the app's version in a triangle |
| `error` | Something went wrong | Leans off a plumb line, or sags under a taut string |

Every figure is drawn once, as geometry, and the engine works out all six from
that one description. The laptop is never drawn broken for its error or half
built for its loading. Its desk sags under a string line, and the same string
line turns up under the bridge and the market stall.

The skill opens on one rule for the agent: **the object says where you are,
and the marks say what is happening.** A trolley sits on a cart page and a door frame on a
page that is gone. Whether the cart is loading or the page is missing is left
to the marks.

## The first set was a building site

The first six figures were the site itself: a wall, a stair, a bridge, a ramp,
a door frame and two tin cans on a string. Each one answered a moment that has
no object of its own.

| Moment | Figure | How it goes wrong |
| --- | --- | --- |
| A page that is gone | A door frame on a step, the door ajar | It leans |
| Integrations and sync | A bridge between two banks, built from both ends | The span sags |
| Uploads and imports | A stone hauled up a ramp on a sledge | The rope goes slack |
| A live connection | Two cans on posts and a string | The string goes slack |

They looked right on the sheet, and I could not put most of them in a product.
Nobody has a screen about a wall. So the library went back to the things
people already have on their screens, in seven shelves: messages, files,
people, money, shopping, time and devices. An inbox, a filing cabinet, a
trophy, a safe, a trolley, an hourglass, a laptop. The building site stayed as
an eighth shelf, for the moments the everyday shelves cannot cover.

The site taught the test every new figure has to pass. It goes up from the
ground in an order that makes sense, like the inbox's stand before its tray
and the tray before the letters in it. It has one part that can change on its
own, for the revision cloud to go round. And it can go wrong in a way you can
see, by leaning or by sagging.

## Moving only when something changes

A figure moves when its state or its value changes, and at no other time. It
does not follow the pointer or breathe while it waits. Loading inks the figure
in, piece by piece in build order, as far as the `value` it is given. With no
value, one piece is built and a bucket goes up and down on the gin wheel at the
top of the scaffold, the only drawing in the library that loops. Under reduced
motion it lands on its state without the trip there.

The workers are off by default, because they never stop moving: each one
shifts between two drawings every few seconds. Every state has to read
without them, so they are never the thing that says what is happening. Turned
on, each has a job that matches the state: marking out the dashed outline,
carrying the next piece up the ladder, sitting on top of the finished work
with its legs over the edge, shrugging beside the plumb line.

In an app, the component takes the state the screen is already in:

**An upload screen** · `upload.jsx`

```jsx

export function Upload({ sent, total, failed, done }) {
  const state = failed ? "error" : done ? "success" : total ? "loading" : "empty";
  return <Ostraca name="ramp" state={state} value={total ? sent / total : undefined} />;
}
```

It renders on the server as plain SVG, so the drawing is there before any
script runs. In the browser, a change of prop animates from the old state to
the new one. The colours are custom properties with a light and a dark value
each, so a page that sets its colour scheme gets the cream pad or the
blueprint without asking, and `dir="rtl"` mirrors the drawing for an Arabic or
Hebrew interface.

## Drawing a new object

Thirty-four figures will not cover every product, so most of the work went
into the skill. It installs into any coding agent that reads skills:

**Install the skill** · `terminal`

```sh
npx skills add ahmedamr-r/ostraca
```

Then ask the agent for an illustration, or call it by name with
`/ostraca coffee cup`. Before it draws, it asks in one message which states
the screen needs and whether the drawing goes into an app or out as one SVG
file for a slide or a design file, with a default for each. If the request
names a moment, such as "something for a fitness app", it offers two or three
objects to pick from.

The agent writes one description file: the object's parts as geometry, in the
order they are built, with the part a revision cloud goes round and the way it
fails. It never writes state code or draws a tick of its own, because the
engine draws every mark the same way for every figure. A check script then
reads the file against the library's rules, and the agent draws contact
sheets of every state in light and dark, looks at them, and fixes what it
sees. The skill is measured against seven requests, each with a written
account of what a good answer to it contains.

## Where it lives

- [skills.ahmedamr.com/ostraca](https://skills.ahmedamr.com/ostraca), every
  figure in any state, and the docs.
- [github.com/ahmedamr-r/ostraca](https://github.com/ahmedamr-r/ostraca), the
  engine, the figures and the skill. A figure request there is the way to ask
  for an object the library does not have yet.
- [ostraca on npm](https://www.npmjs.com/package/ostraca), for `npm i ostraca`.
