# Parity

> Hold the site to the design it copies: capture the design's pages once, and the parity gate compares each built page with them, text, type, colour and place.

When you rebuild a site from a design, the parity gate checks the site still
looks like it. It compares each page's text, fonts, colours and positions with
a reading taken from the design.

## 1. Capture the design, once

Serve the design (any local web server will do), then:

```bash
tools/droost/vendor/bin/droost-parity capture \
  --source http://localhost:5399 \
  --routes /,/about,/contact \
  --width 1280,390
```

This writes the reference to `droost/parity/`: every visible piece of text on
each page, with its box and its look, at each width. Commit it.

Capturing is yours, before a run. During a run the reference is frozen, and
the gate fails if it changes.

A static design's `.html` pages are captured at the path the site will
answer: `--routes /about.html` is held against the site's `/about`.

## 2. Turn it on

```yaml
gates:
  parity: { on: true, required: true, scope: frame, routes: "/", pages: "/" }
```

| Option | What it does |
|---|---|
| `scope: frame` | judge only the header and footer (for the first tickets, before pages exist) |
| `scope: page` | judge whole pages |
| `pages:` | the pages to judge whole, at the first width, while the rest keep `scope` |
| `routes:` | the pages built so far; the others are listed as "not judged" instead of failing |
| `required: true` | a missing reference fails instead of passing with nothing measured |

When you build a site in rungs, widen `routes:` and `pages:` as each page is
built. `droost workflow:intake routes <rung>` prints the right `routes:` value
for a rung.

## 3. What it reports

Each page passes or fails on seven checks. A failure names the check and the
text it is about.

| Check | Asks |
|---|---|
| D1 | Does the page load, without scrolling sideways? |
| D2 | Is every text from the design there, in the same order? |
| D3 | Is the type the same (face, size, weight)? Every heading must match. |
| D4 | Are the colours the same? |
| D5 | Does each text sit in the same place, within a tolerance? |
| D6 | Does the header link to the same places? |
| D7 | Do the header and footer look the same? |

The verdict also says which site it judged and where the reference was read.
A reference read on one platform is judged only on the same one, because
browsers lay out the same page slightly differently.

## Things the client changed

A design sometimes shows something the client decided against, or misses
something the client added. Write the decision down in
`droost/parity/decided.json`, citing the intake question that made it:

```json
{
  "set_aside": [{ "route": "/about", "text": "Learn More", "decided": "Q6", "why": "the client dropped this link" }],
  "added": [{ "route": "/location", "text": "Times are shown in Chicago time.", "after": "Closed", "decided": "Q8", "why": "the client chose the dealership's clock" }]
}
```

An entry with no decision, or naming text the design does not show, is
refused, so the file can only hold real decisions.

## Text that changes by itself

Some text follows the clock: "Open now", "Friday · today". Capture reads such
a page again with the clock moved, across every weekday, and leaves out
whatever changes. The verdict lists those texts as "not judged".
