Gross margin, markup and the contingency buffer

The difference between markup and margin, the reason the app works in margin, and how the contingency buffer is calculated and shown.

Gross margin, markup and the contingency buffer

Markup is what you add to a cost. Margin is what you keep — and it is the
number that has to survive the job, so it is the number the app works in.

The two formulas

Markup on cost:

$$
\text{Price} = \text{Cost} \times (1 + \text{markup})
$$

Margin on price — the one that matters, because a 20% markup is not a 20% margin:

$$
\text{Price} = \frac{\text{Cost}}{1 - \text{Margin}}
$$

Cost Markup Price Margin
$1,000 +20% $1,200 16.7%
$1,000 +25% $1,250 20.0%
$1,000 +43% $1,430 30.0%

Rule of thumb: to hit a margin of m, mark up by m ÷ (1 − m). A 30%
margin needs a 43% markup. Pricing by markup and reporting by margin is how a
contractor ends up surprised in month three.

In the app

Each line stores a cost (unit_cost), a markup (markup_percent) and the
resulting line_total. The Global Gross Margin Controller in the quote
builder sets one margin across every line at once; per-line markup is still
editable, because a callback fee or a warranty line does not deserve the same
treatment as a roof.

Every total the app shows — the quote, each tier package, the PDF, the public
page — comes from one place. The browser displays what the server computed rather
than re-deriving it, which is why the number on screen and the number on the
signed PDF cannot disagree.

The contingency buffer

Contingency is a percentage of the pre-tax subtotal, held for the things that
always show up: sheathing that is rotten under the shingles, a subfloor that
moves once the tile is up. It is added after margin, so it does not silently
become margin, and it can be shown to the client or kept internal:

  • Contingency visible: it prints as its own line on the proposal, which reads
    as honesty about unknowns.
  • Not visible: it stays inside the total. Simpler to explain, and it means an
    unused buffer is yours.

Tax is charged on the material subtotal only — labour and subcontractors stay
exempt — and the permit fee is a flat pass-through with no markup on it.

Found something out of date? The guides live in the repository's docs/ directory — fixing the guide is part of fixing the feature.