# Quote generation — output contract

This is the **output half** of the engine-driven quote path. The engine (the operator's captured
pricing method applied to a job) produces the figures; this contract turns those figures into the
documents the operator issues, each rendered to PDF.

It holds **no** business content. There are no fixed section names, no fixed wording, no fixed brand,
and no fixed page layout here. What each document contains and how it looks is the operator's, held
as their own data (their headings, their narrative, their charts, their logo, colours, contact and
terms, their page size). The same contract serves any trade or service business by reading that
operator's own document definitions.

This is distinct from the lightweight WhatsApp quote in `references/quoting.md`. Use that one for a
quick text quote. Use this one when the operator prices a job from a captured method and issues a set
of reconciling documents.

## What the engine hands you

You render from the engine result. Read it as:

- an ordered set of priced **groups** (the operator's own stages or categories);
- each group an ordered set of **lines**; each line carries its quantity and the quantity's source
  (measurement-derived or entered), its unit, its rate, its cost, and its sell;
- each group's **subtotal**;
- the operator's named **roll-up** steps — whatever sequence of adjustments and taxes they apply
  above the line items, in order;
- the **totals**: the client-visible subtotal and the final total.

The engine guarantees the reconciliation invariant: the group subtotals carried through the roll-up
equal the final total. You never recompute these figures — you display them.

The engine itself, and how a line's quantity, rate, cost and sell are derived, are out of scope here
(that is the compute core). This contract only reads the result.

## The three documents

The operator defines the content and styling of each; the **roles** are fixed, the **contents** are
not. A document is **engine-driven**: a section or line appears **only where the job priced it**.

| Role | Shows | Withholds | Filing scope |
|---|---|---|---|
| **Internal margin-bearing view** | every line's quantity and its source, unit, rate, cost and sell; each group subtotal; the full roll-up; the totals | nothing — this is the operator's own check on profitability before issuing | **admin-only** |
| **Client breakdown** | how the price is composed, at the granularity the operator chooses: the client-facing amount per group or line, the roll-up steps the client sees, and the headline figure | any cost, margin, or internal rate figure (the operator's own unit rate, not a client-facing per-unit price) | client-facing (shared) |
| **Client quote document** | the issued document in the operator's brand: their cover, their narrative or schedule, the client breakdown, the headline price, the acceptance block, and their standing terms | any cost, margin, or internal rate figure (the operator's own unit rate, not a client-facing per-unit price) | client-facing (shared) |

The internal view exists so the operator can confirm the job is profitable before it goes out; it may
expose cost and margin freely. The two client documents **never** surface a cost, margin, or
internal-rate figure. A column or line that shows the price to the client is fine; a figure that
reveals what the work cost the operator, or the markup applied, is a leak.

### The margin boundary is the filing scope

The leak boundary is structural, not a matter of remembering to omit a column. File each document by
its scope, exactly as `references/document-management.md` defines:

- the **internal margin-bearing view** goes to the **admin-only** customer folder
  (`memory/admin/customers/{phone}/`), which the customer never receives;
- the **client breakdown** and the **client quote** go to the customer-facing documents folder
  (`memory/users/{phone}/documents/`).

A document that carries cost or margin must never be written to the shared scope.

## Print fidelity

Each document becomes a PDF through the device's Chromium print pipeline, so the HTML must survive
that pipeline. Start from the A4 print conventions already in `references/invoicing.md` and
`references/document-management.md` — an `@page` size directive, `@media print` styles, and
`page-break-inside: avoid` on blocks that must not split — and keep the operator's own page size on
`@page` (their stationery may not be A4).

A multi-page issued quote needs two things beyond what those siblings show; state them explicitly in
the document:

- page-level chrome — a running header or footer and page numbers — via `@page` margin boxes, never
  absolutely-positioned elements that drift across pages;
- `print-color-adjust: exact` on coloured fills, so the operator's brand fills survive print. The
  renderer prints backgrounds, but make the intent explicit rather than relying on the default.

## Producing the PDF

Render the document as self-contained HTML (styles inline, images by absolute local path), then use
the same path as every other business-assistant document:

1. write the HTML to the document's filing-scope path;
2. `browser-navigate` to it via a `file://` absolute URL;
3. `browser-pdf-save` to an absolute `.pdf` path alongside the HTML;
4. confirm a non-zero byte count from the `Saved PDF to <path> (<bytes>)` line before treating the PDF
   as done.

## Before you hand anything to the PDF tool

Log, for the run: which document roles were produced, each one's page count, and the reconciliation —
each document's displayed total against the engine total. If a document's total does not reconcile to
the engine total, fail loudly and stop. Never ship a document whose figures disagree with the engine.
