The single error struct returned across the public API.
Every malformed-input or edit failure surfaces as
{:error, %PdfEx.Error{reason: atom(), message: String.t()}} — the library
never raises on bad files. reason is a stable atom for matching; message
is human-readable context.