# Agentstead design.md

Guidance for agents and people who build anything that has to look like it was made by Agentstead: marketing pages, docs, blog posts, dashboards, reports, proposals, and one-off pages. The brand is **Civic Grid**. Load this file, link the published stylesheet, and build with the class vocabulary documented below. Do not read the stylesheet into context; the public API here is the whole contract.

- Canonical URL of this file: `https://agentstead.sh/design.md`
- Published stylesheet: `https://agentstead.sh/assets/civic-grid.css`
- Live styleguide with every primitive rendered: `https://agentstead.sh/brand`
- Source of truth for components inside the Phoenix app: `AgentWorkspacesWeb.CivicGrid` (`control_plane/lib/agent_workspaces_web/civic_grid.ex`)

## What Agentstead is

Agentstead gives AI agents durable external identities. A **workspace** is one agent's identity: an inbox, a persistent browser profile, sealed credentials, a second factor, approval gates, and an append-only activity record. Pages exist to make that primitive legible, so every surface should be able to show a workspace as a real, inspectable object rather than describe it in adjectives.

Civic Grid is "external identity as optimistic public infrastructure": a city map crossed with a premium developer tool. Public, precise, colourful, quietly futuristic. Warm paper, navy ink, and six signal colours that each mean one thing.

## Voice

Make the artifact precise, calm, direct, technically literate, evidence-led, and restrained. Build confidence through clarity and proof, never through hype, decoration, novelty, or exaggerated claims.

- Sentence case everywhere, including headings and buttons. Mono labels are the only uppercase text.
- Lead with the concrete thing: the endpoint, the record, the number, the state. `POST /v1/workspaces` beats "our powerful API".
- Prefer a supported statement to evaluative shorthand. Say what the thing does and what it does not; never "blazing", "seamless", "effortless", "next-generation".
- Spell out state in words next to any colour: `Receiving`, `Sealed`, `1 pending`. Colour alone never carries meaning.
- Name things with the product vocabulary: workspace (the parcel), route (how mail, sessions, and approvals reach the responsible human), record (the activity history). Do not invent synonyms.
- Do not let authoring vocabulary from this file (composition, hierarchy, focal, primitive, tone) leak into page copy.

## Priority order

When requirements compete, protect them in this order:

1. Preserve supplied facts, numbers, units, qualifiers, privacy constraints, and task constraints.
2. Preserve the caller's framework, routes, delivery surface, and existing Civic Grid foundation.
3. Make the reader's question, the strongest supported answer, and the material evidence immediately clear.
4. Establish unmistakable Agentstead authorship: signal bar, topbar, Manrope/Inter/IBM Plex Mono, canvas and ink, colour bound to meaning.
5. Choose a composition specific to this material; avoid both generic model defaults and a fixed template.
6. Refine responsive behaviour, interaction, and detail without weakening the hierarchy.

Ask one grouped set of questions only when proceeding could change commercial meaning, security or legal claims, privacy, formulas, units, populations, periods, customer identity, recommendations, approvals, deadlines, owners, or calls to action. Otherwise omit the unknown, label it honestly, and proceed.

## Integrate with the caller's project

Preserve the host framework, file structure, routes, component conventions, and build system. Edit the files that naturally own the experience. When no project exists, semantic HTML plus the published stylesheet is the fallback; do not introduce a framework to render a page.

Inside the Agentstead Phoenix app, render through `MarketingLayout.civic/1` (or a layout that sets `data-brand="civic"` on `<html>` and `cg-root` on `<body>`) and use the `CivicGrid` function components. Outside the app, link the stylesheet once at the document root and use the class names directly:

```html
<!DOCTYPE html>
<html lang="en" data-brand="civic">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700&family=Inter:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="https://agentstead.sh/assets/civic-grid.css" />
  </head>
  <body class="cg-root">...</body>
</html>
```

Rules:

- Every token and colour in the stylesheet is scoped to `:root[data-brand="civic"]`. Without that attribute nothing renders as Civic Grid.
- Use the published CSS unchanged. Page-owned CSS may add page-specific layout from the public tokens (`var(--cg-ink)`, `var(--identity-inbox)`, `var(--font-mono)`, `var(--gutter)`, …) but must never target a published `.cg-*` class, redefine a `--cg-*` token, or restyle a `.cg-*` primitive's layout, typography, surface, border, or controls.
- Page-authored selectors use their own namespace (for example `.report-*`), never `cg-`.
- Never write raw hex values in page CSS or markup. If a colour is not in the token list, it is not in the brand.
- The default network allowlist is the stylesheet, the Google Fonts requests above, `/assets/brand/*`, and assets the caller supplies. No third-party JavaScript, chart libraries, icon kits, stock photography, or analytics without authorisation.
- If the stylesheet cannot be loaded at runtime, copy its exact bytes into the project. Never emit a `file://` URL, a placeholder URL, a translated token system, or a CSS `@import`.

## Work in four passes

### 1. Frame the reader's job

Inspect all material first. Privately establish who opens this page, to decide or understand what; the strongest supported answer; the evidence that earns it; the caveat that could change it; and what should stay available for audit without dominating the first read.

Distinguish observation, derivation, projection, and recommendation. Never invent intent, urgency, certainty, deadlines, approvals, future behaviour, or confidentiality.

Support two reading speeds:

- **Executive path:** identity, title, headings, decisive values, panel titles, and the closing conclusion carry the argument.
- **Audit path:** exact tables, spec lists, code, method, caveats, and sources preserve the record.

Every section must answer a new reader question. Combine duplicates. Keep one evidence home per claim: a table may preserve exact lookup, but a second summary, chart, or card group must not restate the same answer at equal prominence.

### 2. Choose the composition

The first viewport is the argument, not a masthead followed by setup. It may be claim-led, evidence-led, comparison-led, or tool-led. If the reader saw only this viewport they should remember the central relationship or decision.

Name the obvious layout the category suggests, then reject it unless the material earns it. Compare two materially different compositions (topology, density, evidence placement, not palette) before coding.

Map material to geometry before choosing components:

- Magnitude or rank → position or length on a common scale (`cg-metric` strip, `cg-table`).
- Sequence, process, dependency → `cg-checklist`, numbered `cg-section` indices, `cg-technical-panel` code.
- A durable object with several states → `cg-workspace` card or `cg-primitive` tiles; this is the brand's signature evidence object. Use it whenever a real workspace can stand in for prose.
- Qualitative alternatives → aligned rows in `cg-table` or peer `cg-panel`s in one `cg-grid`.
- One conclusion → prose in `cg-lede` / `cg-body`, optionally one `cg-callout`.
- Definitions and vocabulary → `cg-definitions` or `cg-spec`.

Tables for precise lookup, prose for one conclusion, charts only when the relationship is faster to see than read. Do not default to bars because values exist. Do not add a chart library.

Compose the page as a field, not a stack of equal cards. Give each section one focal object with a small number of supporting objects and open space around it. Pace the scroll: alternate dense evidence with quiet prose while keeping one grammar. Repetition is rhythm only when the repeated items are true peers.

End with the resolved decision, the next action, or the open question; let the footer follow quietly. A page must not simply stop after a table or caveat.

Squint test: at a glance the dominant claim or evidence is obvious and the reading path stable. Text-mask test: with the words blurred, hierarchy still shows identity, emphasis, grouping, and progression. If every block has equal weight, redesign before coding.

### 3. Apply the Civic Grid visual system

This section is the design authority. The stylesheet holds the exact values; these rules say when to use them.

#### Authorship shell

Every Civic Grid page opens with the six-colour **signal bar** and a **topbar**, and closes with the **footer**. These are the authorship marks; do not replace them with a hero image, a gradient, or a logo lockup.

```html
<body class="cg-root">
  <div class="cg-signal-bar" aria-hidden="true">
    <span></span><span></span><span></span><span></span><span></span><span></span>
  </div>
  <header class="cg-topbar">
    <div class="cg-container">
      <div class="cg-topbar-inner">
        <a class="cg-topbar-mark" href="/">Agentstead</a>
        <nav aria-label="Primary"><ul class="cg-toc"><li><a href="#…">Section</a></li></ul></nav>
      </div>
    </div>
  </header>
  <main id="main">…</main>
  <footer class="cg-footer">
    <div class="cg-container">
      <div class="cg-footer-inner">
        <span class="cg-label cg-label-plain">Agentstead</span>
        <div class="cg-cluster">…quiet links…</div>
      </div>
    </div>
  </footer>
</body>
```

- Topbar mark: the wordmark text "Agentstead" in the display face, optionally preceded by `/assets/brand/agentstead-mark.svg` at 28–40px. Add a second segment with a slash for a sub-surface (`Agentstead / Docs`).
- Topbar right side: the page's own section links as `cg-toc` (mono uppercase), or at most two `cg-button` actions. Never both a full nav and a row of buttons.
- Footer: one plain label left, a `cg-cluster` of quiet links or a single `cg-status` right. No columns of links, no social icon rows.
- The shell regions separate with the quiet 20% ink border the stylesheet already applies. Do not add extra borders, shadows, or fills to them.
- Reports and proposals may replace nav links with at most two sourced metadata fields (customer, period, purpose) as plain `cg-label`s. Do not invent metadata.

#### Colour carries product meaning

| Token | Hex | Meaning | Where it appears |
| --- | --- | --- | --- |
| `--cg-canvas` | `#F7F4EE` | Page ground | `cg-root` background |
| `--cg-surface` | `#FFFDF7` | Lifted surface | panels, topbar, footer |
| `--cg-ink` | `#142C48` | Text, trust edges, technical panels | all body text, `cg-panel-trust`, `cg-panel-technical` |
| `--cg-muted` | `#56646F` | Secondary text | `cg-lede`, hints, notes |
| `--cg-blue` (routing) | `#3156E3` | Primary action, selection, links, routing | `cg-button`, links, focus ring, `*-routing` |
| `--identity-inbox` (mint) | `#55C7A5` | Mailbox identity and delivery | `*-inbox` |
| `--identity-browser` (sky) | `#82C8F5` | Persistent browser profile and sessions | `*-browser` |
| `--identity-credential` (coral) | `#FF8066` | Stored credentials and secrets; also the "don't" marker | `*-credential`, `cg-list-dont`, field errors |
| `--identity-mfa` (yellow) | `#F4C95D` | Second factor, recovery, warnings that need a person | `*-mfa`, status on ink |
| `--identity-approval` (violet) | `#8B7CF6` | Human approval and policy holds | `*-approval` |
| `--identity-activity` (teal) | `#CCEEE6` | Activity records and history | `*-activity` |

Rules:

- A signal colour appears only when it carries its meaning. A section about credentials is coral-toned; a section about pricing or company is `neutral`. Never pick a tone because it "looks nice" and never rotate tones for variety.
- Use tones through the component suffixes (`cg-label-inbox`, `cg-panel-note-approval`, `cg-status-mfa`, `cg-primitive-browser`, `cg-callout-credential`, `cg-panel-feature-routing`). Do not paint backgrounds with the raw tokens.
- Small text never sits directly on a full-strength signal colour; the components ship pale fills for that reason. Ink on canvas, ink on surface, surface on ink, surface on blue are the only text pairings.
- Success is not green and danger is not red as free-floating semantics. Success is a spelled-out state (`Provisioned`, `Delivered`) in a neutral or meaning-bound status; failure is a spelled-out error string in `cg-field-error` or a `cg-panel-note-credential`.
- Dark surfaces exist in exactly one place: `cg-panel-technical` (ink background) for code, logs, and API responses. Never build a dark hero, dark section, or dark page.

#### Typography

- Display: Manrope 500 with tight negative tracking — `cg-display-xl` (one per page, the h1), `cg-display-lg` (section h2). Headings are short: aim for one line at desktop; break at the clause, never mid-phrase.
- Sub-heading: `cg-heading` (Manrope 600) for h3 inside panels; `cg-panel-title` for a panel's own title.
- Body: Inter via `cg-body` (16px) and `cg-lede` (17px, muted) for the one-paragraph stand-first under a heading. Prose measure stays at 60–72 characters; never run body copy the full width of `cg-container`.
- Mono: IBM Plex Mono via `cg-mono`, `cg-label` (10px uppercase tracked labels), `cg-code-inline`, `cg-code`, `cg-workspace-address`. Anything that is a real identifier (endpoint, address, ID, status word, hex) is mono. Prose is never mono.
- No italics, no serif, no light weights, no gradient text, no text shadows.

#### Layout and spacing

- One `cg-container` (max 1260px, 28px gutters) per section. Sections stack with `cg-section` (120px block padding, collapsing between siblings). The hero uses `cg-hero` with the 50/50 `cg-hero-grid`: copy left, an identity object right.
- Grids: `cg-grid cg-grid-2|3|4|6` for true peers, `cg-split` for a focal object beside its explanation. Never nest grids more than one level.
- Vertical rhythm: `cg-stack` (default) and `cg-stack cg-stack-lg`; horizontal: `cg-cluster`. Do not hand-write margins between siblings.
- Radii: panels 12px, feature panels 28px. Nothing else is rounded (tables, code, inputs use the panel radius or none).
- Shadows: the offset shadow (`10px 10px 0` at 10% ink) belongs to `cg-panel-feature` and `cg-workspace`. Nothing else casts a shadow. No blur shadows, no glows.
- Borders are the quiet 20% ink line; `cg-panel-trust` uses a full-ink edge to say "this is the authoritative record". Use trust sparingly — one per viewport at most.
- Section numbering: `cg-section` takes `index="01"` plus an eyebrow; use it on long pages so the reading path is countable. Keep indices consecutive.

#### Motion and imagery

- Transitions are 200ms ease-out and collapse under `prefers-reduced-motion`. No entrance animations, parallax, scroll-jacking, autoplaying video, or animated gradients.
- Campaign art is built from product structure: a `cg-workspace` card, a `cg-primitive` tile grid, a technical panel showing a real response, a `cg-signal-bar`. Photography, 3D renders, illustrated landscapes, and abstract gradients are off-brand. Screenshots of the product are fine when they show real UI at real proportions.
- Icons: none in the component library by design. Use the mono label (`INBOX`, `MFA`) where an icon would have gone. Never add an icon kit.

#### Public class vocabulary

Use exactly these names. Anything not listed is not part of the brand contract.

**Root and layout** — `cg-root`, `cg-container`, `cg-section`, `cg-section-header`, `cg-section-header-lede`, `cg-hero`, `cg-hero-grid`, `cg-hero-copy`, `cg-grid`, `cg-grid-2`, `cg-grid-3`, `cg-grid-4`, `cg-grid-6`, `cg-split`, `cg-stack`, `cg-stack-lg`, `cg-cluster`, `cg-divider`, `cg-sr-only`.

**Shell** — `cg-skip-link`, `cg-signal-bar`, `cg-topbar`, `cg-topbar-inner`, `cg-topbar-mark`, `cg-toc`, `cg-topbar-actions`, `cg-menu-trigger`, `cg-mobile-nav`, `cg-footer`, `cg-footer-inner`.

**Type** — `cg-display-xl`, `cg-display-lg`, `cg-heading`, `cg-lede`, `cg-hero-qualifier`, `cg-body`, `cg-prose` (long-form rendered markdown: blog posts, docs, legal), `cg-mono`, `cg-label`, `cg-label-plain`, `cg-label-index`, `cg-label-{tone}`.

**Controls** — `cg-button`, `cg-button-secondary`, `cg-button-quiet`, `cg-button-sm`, `cg-button-row`, `cg-copy-button`, `cg-copy-status`, `cg-status`, `cg-status-on-ink`, `cg-status-{tone}`.

**Panels** — `cg-panel`, `cg-panel-title`, `cg-panel-media`, `cg-panel-trust`, `cg-panel-note`, `cg-panel-note-{tone}`, `cg-panel-feature`, `cg-panel-feature-{tone}`, `cg-panel-technical`, `cg-panel-technical-header`, `cg-callout`, `cg-callout-{tone}`.

**Evidence** — `cg-table`, `cg-spec`, `cg-definitions`, `cg-checklist`, `cg-checklist-index`, `cg-list`, `cg-list-do`, `cg-list-dont`, `cg-list-marker`, `cg-metric`, `cg-metric-value`, `cg-metric-note`, `cg-code`, `cg-code-inline`, `cg-swatch`, `cg-swatch-chip`, `cg-swatch-body`, `cg-swatch-role`, `cg-swatch-meaning`.

**Product objects** — `cg-primitive`, `cg-primitive-{tone}`, `cg-primitive-head`, `cg-primitive-body`, `cg-primitive-name`, `cg-primitive-copy`, `cg-workspace`, `cg-workspace-head`, `cg-workspace-identity`, `cg-workspace-name`, `cg-workspace-address`, `cg-workspace-services`, `cg-workspace-service`, `cg-workspace-service-{tone}`, `cg-workspace-service-state`, `cg-workspace-service-detail`, `cg-workspace-foot`.

**Forms** — `cg-field`, `cg-field-label`, `cg-field-hint`, `cg-field-error`, `cg-input`, `cg-textarea`, `cg-select`, `cg-check`.

`{tone}` is one of `routing`, `inbox`, `browser`, `credential`, `mfa`, `approval`, `activity`. `neutral` is the default and has no suffix.

Component shapes (markup the stylesheet expects):

```html
<!-- Section with numbered eyebrow -->
<section class="cg-section" id="security">
  <div class="cg-container">
    <header class="cg-section-header">
      <div>
        <p class="cg-label cg-label-plain cg-label-credential">
          <span class="cg-label-index">03</span><span aria-hidden="true">/</span><span>Security</span>
        </p>
        <h2 class="cg-display-lg">Your model never sees the password</h2>
      </div>
      <p class="cg-lede cg-section-header-lede">One sentence of stand-first.</p>
    </header>
    …
  </div>
</section>

<!-- Status word next to its colour -->
<span class="cg-status cg-status-inbox">Receiving</span>

<!-- Technical panel: ink surface, real response -->
<div class="cg-panel-technical">
  <div class="cg-panel-technical-header">
    <span class="cg-label cg-label-plain">POST /v1/workspaces</span>
    <span class="cg-status cg-status-on-ink">202 Accepted</span>
  </div>
  <pre class="cg-code"><code>{ "id": "ws_184", "state": "provisioning" }</code></pre>
</div>

<!-- Field with an explicit error -->
<div class="cg-field">
  <label class="cg-field-label" for="address">Inbox address</label>
  <input class="cg-input" id="address" aria-invalid="true" value="scout@agents.agentstead.sh" />
  <p class="cg-field-error">That address is already claimed on this org.</p>
</div>
```

### 4. Verify before shipping

Run this list against the rendered page, not the source:

1. Signal bar, topbar, and footer present; `data-brand="civic"` on `<html>`, `cg-root` on `<body>`.
2. Exactly one `cg-display-xl`. Section headings are `cg-display-lg` and read as a coherent outline on their own.
3. Every signal colour on the page can be explained by its meaning. No decorative tones, no raw hex.
4. Every coloured state has a word next to it.
5. Tables and technical panels use the full width available to them; prose does not exceed ~72 characters per line.
6. No photography, gradients, icons, dark sections, blur shadows, or animations.
7. Supplied facts, numbers, units, and qualifiers survived verbatim. Unknowns are labelled, not filled.
8. The page ends with a conclusion or next action, then the footer.
9. Keyboard focus is visible (blue ring) on every interactive element; the skip link exists on full pages.
10. At 390px wide nothing overflows; `cg-toc` collapses and grids stack.

## Named anti-patterns

Recognise these by name and remove them. They are the failures that keep recurring in generated Civic Grid pages.

- **Rainbow rotation** — cycling tones across peer cards for variety. Peers about the same thing share one tone or none.
- **Colour-only state** — a green dot, a red border, a yellow pill with no word. Add the word or drop the colour.
- **Terminal cosplay** — dark pages, green-on-black, blinking cursors, ASCII borders, fake prompts. The one dark surface is `cg-panel-technical`, and it shows real output.
- **Robot theatre** — robots, brains, circuit boards, glowing eyes, cyberpunk skylines, surveillance imagery. Show the workspace instead.
- **Landscape hero** — a full-bleed photograph, render, or video behind the h1. The hero is 50/50: copy beside an identity object.
- **Card wall** — every section a grid of identical bordered cards with an icon, a title, and two lines. Pick a focal object per section.
- **Shouting caps** — uppercase headings or buttons. Only `cg-label` and `cg-toc` are uppercase, and they are mono.
- **Mono prose** — paragraphs set in the code face. Mono is for identifiers.
- **Gradient authority** — gradient backgrounds, gradient text, glass blur, glow shadows to signal "premium". Premium is the offset shadow, the trust edge, and restraint.
- **Icon fog** — an icon kit sprinkled next to every heading. The brand has no icons; use mono labels.
- **Prose-width table** — an evidence table squeezed to the paragraph measure while the section has room. Tables span the container.
- **Redundant summary** — the same numbers in a metric strip, a chart, a table, and the conclusion. One home per claim.
- **Confidence inflation** — "seamless", "instantly", "enterprise-grade", "bank-level", any claim the material does not support.
- **Dashboard chrome the product cannot render** — fake charts, fake sparklines, fake avatars. If the API cannot return it, the page cannot show it.
- **Ceremony preamble** — a masthead, then "Introduction", then "Overview", then the point. The first viewport is the point.

## When the material is thin

Improve selection, hierarchy, comparison, or explanation. Leave gaps honest with a labelled unknown. Never fill an evidence gap with panels, borders, colour fields, decorative code, or stock imagery. A shorter page that says what is known is on-brand; a longer page that decorates is not.
