Logo — three separate faults, all of which had to be fixed for the
letterhead logo to print at all:
1. receipt.html hardcoded '/wfdash-logo.png' for the sale slip, so it
printed the app's bundled mark (the solid black W block) and never
looked at the letterhead at all.
2. The paths that DID use the letterhead (printTest, cashup) passed
PocketBase's fully-qualified cross-origin URL into imageToRaster(),
which draws to a <canvas> — getImageData() taints and throws on a
cross-origin image, so the .catch(() => null) silently dropped the
logo. pos-letterhead-service now returns a same-origin
/api/v1/files/... URL (per AGENTS.md's file-URL rule).
3. letterhead_settings wasn't whitelisted in that file proxy, so the
same-origin URL would have 403'd.
Verified against the live WESTSCOTT letterhead: its SVG rasterizes to
384x137 at ~15% ink coverage (line art), no tainted canvas.
Also fixes the company name never printing: every builder read
`letterhead.name`, but the POS letterhead record exposes
`display_name` — so the name line silently rendered empty on every
slip, on screen and on paper.
Delivery note now matches the sale slip, per request: gains the logo
and business_info blocks and the same 2x-size title, instead of being
a stripped-down variant. This also reconciles the transport
divergence flagged earlier (Bluetooth baked business info into its
header; the network builder omitted it entirely) — it is now one
reorderable business_info block on both.
resolveBlocks() now slots a newly-shipped block in at its intended
position rather than appending it to the end. Without this, any
letterhead with an already-saved layout would have printed the new
logo/business_info blocks BELOW the signature line.
Two compounding issues, both pre-existing (this exact <span>-joining
pattern and CSS was carried over unchanged from the old settings.html
preview I moved in the previous commit):
1. Preview lines are joined as adjacent <span> elements with no
separator, so without an explicit block display they render as
one continuous inline line instead of stacked rows.
2. .receipt-preview sits directly in body's flex-column layout and
has overflow-x:auto — per the CSS Flexbox spec, an overflow-bearing
flex item's automatic minimum size becomes 0 instead of its content
size, so the flex column was free to squeeze it down to a sliver
regardless of its 19 lines of content.
Fixes: span{display:block} for the per-line stacking, flex-shrink:0
so the flex column can't shrink it below its content height.