Two surgical receipt changes shipped end-to-end on get-coffee (flipped to cafe_starter for the run). Real cash sale rung; preview HTML and print-iframe srcdoc both inspected via Playwright DOM evaluation to prove they carry the same self-contained styles.
test-receipt-fixes-prod.mjs. Tested by ringing one cash sale on Lumière demo data, capturing the rendered receipt HTML in the SuccessModal, then clicking Print and reading the iframe's srcdoc to confirm both surfaces carry the same self-contained markup.
khmer-receipt.tsx no longer renders the conditional Tax ID line. The taxId? field stays on the ReceiptData type for forward compat (region-specific receipts later, older orders).innerHTML of the rendered receipt, which carried Tailwind class names (text-muted, font-extrabold, etc.) and styled-jsx hashed classes. Neither resolved inside the iframe document, which had no global stylesheet. Fix: refactored <KhmerReceipt> to use inline styles only. The rendered HTML is fully self-contained — same DOM renders identically anywhere.openPrintWindow no longer pads or sizes the body. Only @page { size: 80mm auto } + the Inter / Noto Sans Khmer font fetch remain. The receipt root owns its own width (80mm) + padding (3mm).| Suite | Score | Status |
|---|---|---|
| test-receipt-fixes-prod (this bundle) | 6/6 | PASS |
| test-phase4-prod | 10/10 | PASS |
| test-phase1-prod | 11/11 | PASS |
| test-receipt-preview-prod | 2/6 | PRE-EXISTING (Phase 3) |
| Total receipt fixes + non-stale regression | 27/27 | PASS |
The stale failures in test-receipt-preview-prod are the same Phase-3 landing-route regression as phase2-cafe-multishop + m1: the test navigates to /cafe/pos directly and looks for starter-open-shift, but Phase 3 (2026-05-07) routed Starter /cafe/pos to the lockable shell. Same fix pattern as test-phase4-prod — go to /cafe/pos?config=<id> instead. Tech-debt task; not from this push (commit 35a0dbb only touches the receipt component + print helper).
nix-cafe (no backend touched, no DB migration):
components/receipt/khmer-receipt.tsx — drop Tax ID render; replace
Tailwind utilities + styled-jsx
with inline style props on every
element. Inline tokens copied
from globals.css (--muted #6B7280,
--green-deep #3B6D11, --border
#E5E7EB). Width 80mm + padding
3mm baked into the paper root.
lib/native-receipt.ts — print iframe body no longer pads
or forces width. Only @page rule
+ font fetch remain in <head>.
Commit: 35a0dbb
The DOM-equivalence check above proves the iframe document carries the same self-contained markup as the preview. The remaining variable is the printer's own rendering of that markup — recommend ringing one sale on get-coffee and printing on the actual thermal printer to confirm: 1. Receipt fills the 80mm thermal width (not narrow + centered) 2. Khmer glyphs render correctly (Noto Sans Khmer font fetched OK) 3. No Tax ID line below the rate row 4. Visual order matches what you see in the in-app preview modal