// Package report writes the two things a shoot produces: a page a person
// reads, and a file Claude reads.
//
// They are separate on purpose. A person wants the pictures side by side,
// worst first, in one file they can open from anywhere. A model wants a
// list of paths and numbers and no HTML at all -- handing it the report
// would spend most of a context window on base64.
package report
import (
"bytes"
"encoding/json"
"html/template"
"os"
"path/filepath"
"sort"
)
// Shot is one screen's outcome.
type Shot struct {
Name string `json:"name"`
// Before, After and Diff are paths, relative to the output directory.
// Before and Diff are empty in review mode, which has no baseline.
Before string `json:"before,omitempty"`
After string `json:"after"`
Diff string `json:"diff,omitempty"`
// Moved says whether this shot changed enough to be worth a look.
Moved bool `json:"moved"`
// Verdict is the one-line summary: a pixel count, or why not.
Verdict string `json:"verdict"`
// Error is set when the shot could not be taken at all.
Error string `json:"error,omitempty"`
// Past is how many CSS pixels the rendering extends beyond the
// viewport it was taken for, and Ink says whether anything is drawn
// out there. A page wider than its phone scrolls sideways, which is
// always a bug; whether there is content past the edge is what says
// how big a one. Both are zero and false on a page that fits.
Past int `json:"overflow,omitempty"`
Ink bool `json:"overflow_ink,omitempty"`
// Width and Height are the candidate rendering's size. The report