Behaviour + facade for invoice-specific PDF rendering.
This seam is intentionally narrower than Accrue.PDF: invoice rendering
starts from Accrue.Invoices.RenderContext, not from raw HTML.
That lets Accrue use a native document engine like Rendro by default while
preserving the legacy HTML-based Accrue.PDF contract for ChromicPDF and
custom callers.
Summary
Types
@type opts() :: keyword()
Callbacks
@callback render(Accrue.Invoices.RenderContext.t(), opts()) :: {:ok, binary()} | {:error, term()}
Functions
@spec impl() :: module()
@spec render(Accrue.Invoices.RenderContext.t(), opts()) :: {:ok, binary()} | {:error, term()}