# Manifest for agents

You lay out pages with semantic HTML, `core.css` and the attributes below. Nothing else.

## Rules

1. Write semantic HTML first: `header nav main aside article section form label fieldset table dl ul button a`. Native elements are already styled.
2. Composition is set only by `data-l`. The same eight relations work at every scale: page, region, card, field. Nest them freely.
3. No numbers in markup: no `style`, no classes, no sizes. Space, type and radius come from the place an element stands in.
4. Use only the attributes and values listed here. Anything else is an error.
5. After writing, run `node check.mjs page.html` and fix every problem it reports. `"ok": true` is done.

## Relations: `data-l`

| value | meaning | children |
|---|---|---|
| `stack` | one under another | any |
| `cluster` | small things in a wrapping row (buttons, tags, links) | short items |
| `split` | main beside side; folds into a stack when main gets narrow | 2; mark the side with `data-side` (default: first child) |
| `switch` | equal parts in a row, all into a column at once when narrow | 2–4 peers |
| `grid` | many equal things, as many columns as fit | many peers |
| `reel` | horizontal strip scrolling inside itself; wrap wide tables in it | items or one `table` |
| `center` | page column of comfortable width | one |
| `cover` | tall area with its content in the middle | any |

Any element may carry `data-surface` and `data-tone`. `data-space` applies to its own relation only and is not inherited. The side of a `split` sizes itself (about 28% of the split, 8–20rem).

Each relation except `cluster` and `reel` is a *place*: its children size space, type, radius and headings relative to it. A `h2` in a narrow card is smaller than a `h2` on the page. That is intended; pick heading levels by meaning, not by size.

## Modifiers

| attribute | values | effect |
|---|---|---|
| `data-space` | `none` `tight` `loose` | gap of this relation |
| `data-side` | — | on a child of `split`: the side part |
| `data-push` | — | on a child of `stack`/`cluster`/`cover`: push it and the following ones to the end |
| `data-pad` | — | padding without a surface |
| `data-optional` | — | secondary content; disappears when its place is narrower than 16rem |
| `data-surface` | `raised` `outline` `accent` | a panel with padding and radius; nested panels deepen by themselves |
| `data-tone` | `quiet` `strong` `accent` `danger` `ok` `warn` | emphasis by intent (`mark` texts wrap, keep them short); on `button`: `accent` = primary, `danger` = destructive, `quiet` = minor |
| `data-theme` | `light` `dark` | colour scheme for this subtree (default follows the system) |
| `data-density` | `compact` `comfy` | density for this subtree |

## Patterns

Page:
```html
<body><div data-l="center" data-pad><div data-l="stack" data-space="loose">
  <header data-l="cluster"><strong>Name</strong><nav>…</nav><button data-push data-tone="accent">Main action</button></header>
  <div data-l="split"><aside data-side>…</aside><main data-l="stack">…</main></div>
</div></div></body>
```

Card (the same at any size):
```html
<article data-surface="raised" data-l="stack">
  <div data-l="split" data-space="tight"><img data-side src="…" alt="…"><div data-l="stack" data-space="tight"><h2>Title</h2><div data-l="cluster" data-space="tight"><mark data-tone="ok">Active</mark></div></div></div>
  <p data-optional>Secondary description.</p>
  <dl><div><dt>Label</dt><dd>Value</dd></div></dl>
  <div data-l="cluster"><button data-tone="accent">Do</button><button data-tone="quiet">Skip</button></div>
</article>
```

Form field (label beside input when wide, above when narrow):
```html
<label data-l="split"><span data-side>Label</span><input name="x"></label>
<label><input type="checkbox" name="y"> Option</label>
```

Metric tile (in a `switch` or `grid`):
```html
<article data-surface="raised" data-l="stack" data-space="tight"><span data-tone="quiet">Documents</span><data value="38">38</data></article>
```
`data` shows a value as a figure; inside `p li td dd` it stays plain text.

List of people or items (a `ul` with `data-l` has no bullets; add `role="list"` to keep list semantics in Safari):
```html
<ul role="list" data-l="stack" data-space="tight">
  <li data-l="cluster" data-space="tight"><strong>Name</strong><span data-tone="quiet">role</span><mark data-push data-tone="ok">online</mark></li>
</ul>
```

Navigation: `<nav aria-label="…"><ul role="list" data-l="cluster"><li><a href="…">…</a></li></ul></nav>`.

Form: `<form data-l="stack">`; group with `<fieldset data-l="stack"><legend>…</legend>…</fieldset>`; long text (`textarea`) in a plain `label` (above), short inputs in `label data-l="split"`; actions in a `cluster`: submit `data-tone="accent"`, cancel/reset `data-tone="quiet"`.

Headings: one `h1` per page for its subject (usually the main card or main area title, not the site name); then `h2` for sections, `h3` inside them.

Status: `<mark data-tone="ok|warn|danger|accent|quiet">Text</mark>`.
Key–value facts: `<dl><div><dt>…</dt><dd>…</dd></div>…</dl>` (columns as many as fit).
Wide table: `<div data-l="reel"><table>…</table></div>`.
Peers in a row: `switch` for 2–4, `grid` for more.

## Checker problems

`page-scroll-x` page wider than the screen · `escapes-parent` element sticks out of its parent · `collapsed-container` a place got no width (a relation inside something sized by its content, e.g. an inline element or an absolutely positioned box) · `narrow-measure` prose in a column under ~15em: move it, mark it `data-optional`, or change the relation · `text-squeezed` · `text-too-small` · `target-too-small` (under 24×24) · `contrast` · `vocabulary` unknown attribute or value · `numbers-in-markup`.
