# `Accrue.Invoices.Components`
[🔗](https://github.com/szTheory/accrue/blob/accrue-v0.3.0/lib/accrue/invoices/components.ex#L1)

Phoenix.Component function components shared by email (via
`Accrue.Emails.HtmlBridge` + `<mj-raw>`) and PDF (via
`Accrue.Invoices.Layouts.print_shell/1`).

## Single source of truth

Both the email HTML body and the PDF body assemble these four
components (`invoice_header/1`, `line_items/1`, `totals/1`,
`footer/1`) against the same `RenderContext`. That is the entire
point of the Wave-2 render architecture — one component library,
two output pipelines, byte-identical money strings.

## Inline-style discipline (Pitfall 2)

Every structural element carries its CSS via `brand_style/1`, which
reads from the frozen branding snapshot in `@context.branding`.
MJML's post-render CSS inliner does NOT descend into `<mj-raw>`
blocks — classname-only styles would be invisible in the final
email. Inline-or-nothing.

## Transactional-only footer (D6-07)

Accrue emails are transactional (receipts, dunning, invoice
notifications) — CAN-SPAM exempts them from opt-out requirements,
and adding an opt-out link to a receipt is actively harmful UX.
The footer intentionally renders `business_name` + `support_email`
+ conditional `company_address` and NOTHING ELSE.

# `footer`

## Attributes

* `context` (`:map`) (required)

# `invoice_header`

## Attributes

* `context` (`:map`) (required)

# `line_items`

## Attributes

* `context` (`:map`) (required)

# `totals`

## Attributes

* `context` (`:map`) (required)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
