The page navigation is complete. You may now navigate the page content as you wish.
Skip to main content

AI agents

Hand an AI coding agent i80 and get idiomatic, on-brand UI back.

You can point an AI coding agent — Claude, Cursor, Copilot — at i80 and have it build screens that look and behave like the rest of your product. i80 is made for this: the whole system is a stylesheet plus <i80-*> tags, and there is a machine-readable list of every tag the agent can read before it writes a line of markup.

This page is the human version of that brief. The agent reads /llms.txt and /elements/components.json; you read this.

Give your agent the guide

Paste this into your agent, or put it in a project rule file:

Build the UI with the i80 Design System. Follow https://design.i80.dk/llms.txt:
load components.css and i80.js (pinned to a version), add the box-sizing reset,
and use only tags and attributes from https://design.i80.dk/elements/components.json.
Write native elements (button, input, form, table) inside the tags so server-rendered
markup keeps its names, ids and CSRF. Do not add any font or script from another origin.

Two files back it up, both meant to be read by a tool:

The rules it has to follow

These are the few things that go wrong when an agent guesses instead of reading, so they are worth stating up front:

How it should build

A reliable order for a build:

  1. Read components.json and pick the tags the screen needs.
  2. Load the files once at the top of the page, with the reset and base.css for the page font.
  3. Compose from tags, writing native elements inside them for anything the server renders.
  4. Lay the page out with the primitives: <i80-flex> and <i80-grid> to arrange, <i80-app-frame> for a whole screen (header, side nav, main, footer), <i80-page-header> at the top of a view.
  5. Keep the content rules: one <h1> matching the title, a real heading outline, sentence-case headings, short lines. They are listed in /llms.txt and in full under Content and page structure.
  6. Check the result: every <i80-*> on the page is a real tag, and the reset is present.

A worked example

Prompt: A "New plan" form — a name field, an owner, and Save / Cancel.

A good agent reads the attributes for i80-text-input, i80-select and i80-button, then writes:

<form method="post" action="/plans">
  <i80-flex direction="column" gap="16">
    <i80-text-input label="Plan name" name="name" placeholder="Q3 launch" required></i80-text-input>
    <i80-select label="Owner" name="owner" value="ada">
      <option value="ada">Ada</option>
      <option value="grace">Grace</option>
    </i80-select>
    <i80-button-set>
      <i80-button color="primary"><button type="submit">Save plan</button></i80-button>
      <i80-button color="secondary">Cancel</i80-button>
    </i80-button-set>
  </i80-flex>
</form>

It submits like a plain form: the <input>, <select> and submit <button> are real elements, i80 only styles them. In a Django or Jinja template the field is the server's own:

<i80-text-input label="Plan name" error="{{ form.name.errors.0 }}">
  {{ form.name }}
</i80-text-input>

When the output is wrong

Most mistakes trace back to not reading components.json:

The machine-readable files