Row 1: Date | Vendor (grow) | Currency | FX rate
Row 2: Description (grow) | Receipt | Amount
Currency and Receipt share the same x position; FX rate and Amount share the same x position.
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1
The last item divider plus two double-rule lines produced three blue lines.
Removed the item divider and the double-rule pair; replaced with a single
line at thickness 3 (double the standard 1.5).
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1
- Move inter-line separator from bottom to top of each expense line;
skip on first line and on page breaks (justBroke flag) so the
continuation header is never followed immediately by a divider
- Increase needSpace from lh*5 (70pt) to lh*7 (98pt) to match the
actual line block height (~6lh + 16pt), preventing content from
overrunning M.bottom and bleeding into the footer area
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1
- New config key date-format (default DD/MM/YYYY) controls date display
throughout the form and PDF output
- formatDate(iso) converts stored YYYY-MM-DD to the configured display format
- parseDate(str) converts user input back to YYYY-MM-DD for state storage
- All three date inputs (line date, period from/to) switched from type=date
to type=text with format placeholder, removing browser locale dependency
- PDF line dates, period header, and continuation header all use formatDate()
- Filename stays in YYYY-MM-DD for safe file naming
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1
state.baseCurrency was set to CFG['currency-base'] at declaration time,
but CFG is only populated after await loadConfig(). Reading a property of
undefined throws synchronously, crashing the script before init() runs.
Move the assignment to after loadConfig() resolves in init().
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1
- Remember the last valid FX rate entered per currency in state.fxRateMemory;
pre-fill it when staff picks the same currency on a new line.
- Move Remove button to top-right of item header (alongside label);
Subtotal moves below the name input, right-aligned in its own row.
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1
Replace static base currency badge with a currency dropdown (makeCDD).
Changing the selection updates state.baseCurrency, re-renders all item/line
blocks so closures capture the new base, and recalculates totals. All
dynamic references to CFG['currency-base'] replaced with state.baseCurrency.
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1
- item-name: change flex:1 to width:100% since it's not in a flex container
- FX rate: add grow class to fgrp and set input width to 100% so it extends to the right edge
https://claude.ai/code/session_014uUwDBtG5y5FuWcy5zqVD1