Guide

How to keep AI-generated dashboards consistent.

The second screen your agent builds rarely matches the first. Here is why it happens and three changes that stop it, each one something you can open and check in this repository.

The problem

The second screen never matches the first

Ask an AI coding agent for an analytics dashboard, then ask for a settings page. Both work, and they do not look like the same product: the buttons have different radii, the grays differ by a shade, the spacing follows a different rhythm. Nothing is broken. Each screen was generated on its own, and nothing told the agent to reuse what the first one decided. The result is design drift, and it grows with every screen.

Why it happens

  • No shared tokens

    Each screen picks its own colors, spacing and radius, so two screens made an hour apart use two slightly different grays and two different paddings.

  • No component set

    With nothing to reuse, the agent writes buttons, tables and cards from memory on every prompt, and memory differs from prompt to prompt.

  • No rule the agent follows

    Nothing in the repository says what to do instead, so every prompt starts from the agent's defaults, not from your product.

The fix

Three mechanisms, one per cause

Each one removes a cause of drift. Together they give the agent something to reuse and something to obey.

One token file

Color, spacing, radius, shadow and type scale are CSS variables defined once in theme.css. Components read semantic tokens such as bg-primary and text-tertiary and never hard-code a value, so editing the file changes every screen. See Theming.

A dashboard and a settings page, rendered live. They are different screens that share one token file, so their colors, type and corner radius change together.

One component set

The agent installs buttons, tables, cards and charts from the same registry instead of rewriting them. There are 89 published component groups, built on React Aria Components, and the full-page examples above are assembled from them. Browse them in Components.

A rule the agent reads

The Proper UI Skill is a file in your repository that the agent reads before it writes UI. Its component rules, the same ones listed under “Writing component code” in this repository's AGENTS.md, are:

  • React Aria props, not DOM props: onPress not onClick, isDisabled not disabled.
  • Semantic tokens only: bg-primary, text-tertiary, never bg-purple-600 or p-[13px].
  • No dark: utilities: a .dark-mode class on an ancestor repoints every token, so a token-based component is already correct in both themes.
  • Logical properties for anything directional: ms-* and pe-* not ml-* and pr-*, so dir="rtl" works.
Try it

Set up, then ask for a dashboard

Two commands, then one prompt. Run the first in your project.

1. Install the Skill (Claude Code)
npx @properui/cli@latest agent init --client claude
2. Add the MCP server (Claude Code, remote)
claude mcp add --transport http properui https://properui.dev/api/mcp

Using Codex, Cursor or another client? Change --client to codex, cursor or all, and find the MCP setup for your client on the MCP page.

Prompt

Build an analytics dashboard with KPI cards, a revenue chart and a recent activity table using Proper UI

Know the edges

Limits, plainly

  • The components are React 19 only. For Vue, Angular, Svelte, Astro or plain HTML you get the same tokens plus @properui/html and @properui/elements, a smaller curated set. See Frameworks.
  • Examples ship with placeholder data and demo assets. Replace them before anything reaches a user.
  • A rule is an instruction, not a guarantee. The agent can still ignore it, so run npx @properui/cli@latest check, which flags raw palette classes and arbitrary values, and review the result.
  • Shared tokens keep colors, spacing and type aligned. They do not make a layout right for your users. That is still a design decision.
  • Zero axe violations in the test suites is not the same as fully accessible. Automated checks miss things such as focus order and screen reader wording. See Accessibility.
Questions

Frequently asked questions

Why do AI-generated screens drift apart?

Each prompt is generated on its own. Without shared tokens, a reusable component set and a written rule, the agent fills every gap from its defaults, and those defaults vary from one prompt to the next.

Does this only work with Claude Code?

No. agent init also supports Codex, Cursor and Lovable, and the MCP server works in any client that supports MCP. See For Claude Code and the MCP page.

Can I use my own brand colors?

Yes. Every visual decision is a CSS variable in theme.css. Editing the base palette re-brands every installed screen at once, including dark mode. See Theming.

How do I catch drift that slips through?

Run npx @properui/cli@latest check. It flags raw palette classes and arbitrary values that should have been semantic tokens. Over the local MCP package the same check is the check_tokens tool.

Give the agent something to reuse.

Browse the components, then read how tokens work.