Files
accounted/app/api
Mattsson 32721b9f61 feat(invoices): diagonal UTKAST/DRAFT watermark on draft PDFs instead of the top-margin banner (#2441)
* feat(invoices): mark draft PDFs with a diagonal UTKAST/DRAFT watermark instead of a banner

Why the problem occurred: the draft marking was a boxed yellow banner in
the page's top margin. It stayed out of the flow (#2369) but still read as
UI chrome pasted on a document, and carried a two-line legal sentence that
nobody reads on a preview.

What was removed: the banner block, its three styles and the four legal
sentences (sv+en). The draft state is now one word, bold, rotated -35deg at
14% opacity, centred on every page, the way a stamp marks paper. The
download dialog (#2399) already explains why a draft is not a valid
invoice before the file exists, so the PDF does not repeat it.

Why this shape: rotation and opacity sit on a padded wrapper View so the
word turns about its own centre and the Text keeps a plain type style.
The overlay is absolutely positioned over the page box and `fixed`, so the
document underneath previews pixel-identical to the final print; a test
asserts the first row sits at the same y as on a sent invoice. BETALD and
MAKULERAD banners are unchanged (separate concern).

Fixes #2437

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D9wvsGnvu5tHGqYnJnjnaB

* fix(invoices): darken the draft watermark so it survives a greyscale print

Skeptic refutation: #6b7280 at 0.14 composites to about 92% brightness on
white, which a monochrome print or greyscale scan drops, and a numbered
draft otherwise prints the FAKTURA title, its number and an OCR like an
issued invoice. Now #4b5563 at 0.3 (about 79% brightness), with a test
pinning the composited grey between 70% and 85% so neither extreme can
creep back in.

Refs #2437

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(invoices): paint the draft watermark last so opaque boxes cannot cover it

Skeptic refutation (correctness and regression, independently): the
overlay was the first child of the Page. react-pdf paints children in
document order and `fixed` does not hoist, so the customer box and the
full-width payment section (opaque #f5f5f5 / #f8f9fa) painted over the
word. On a two-page draft the last page, the one with totals, bankgiro
and OCR, lost the word entirely.

The overlay is now the last child of the Page, behind a single
isDraftMarked flag that also keeps the cancelled > draft > paid banner
precedence. A new test inflates the rendered PDF content streams and
asserts the UTKAST glyph run comes after the last rectangle fill on
every page, so the element tree alone can no longer pass while the
paint order is wrong.

Refs #2437

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(invoices): note the English DRAFT label in the download-decision comment

CodeRabbit on #2441: the comment said every draft is stamped UTKAST; an
English document says DRAFT.

Refs #2437

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 18:11:43 +02:00
..
2026-07-25 22:56:17 +02:00
2026-07-23 16:16:55 +02:00
2026-07-05 03:05:09 +02:00
2026-07-08 09:54:46 +02:00