On /income/invoices at tablet width the expanded invoice detail was unreadable
and the booking control was effectively unreachable.
- The line-item table is rendered inside a <td> of the invoice list's own
scrollable table, so its 1200px width stretched the OUTER table to 1234px and
the whole list scrolled sideways whenever a row was open. The detail is now
measured with a ResizeObserver and given that pixel width, so it can no longer
influence the outer table.
- Both tables' first columns are sticky left-0, and two nested stickies at the
same offset stack on top of one another: the invoice number, the site and the
period printed over each other. The detail wrapper is now sticky left-0 z-20,
above the outer cell's z-10, so the inner table scrolls in its own box.
- The unbooked row tint was bg-[#D1495B]/[0.04] — 96% transparent — so every
column a sticky cell covered bled through it on scroll. The tint is now the
solid #FDF3F4 (dark #292934), repeated exactly on the sticky cells.
- The KPI row was flex-wrap, which sizes tiles by CONTENT, so the wide "booked
to income" tile pushed the third one onto a second row below ~644px. It is a
grid-cols-3 now, with the figures sized to the column.
- The machine picker and the site dropdown in the Booked to cell were flex
children and compressed into each other by ~12px instead of sitting side by
side. Both are shrink-0 now.
- Booking a line always saved on selection with no Save button, which read as
"nothing happened". Unmatched rows now say so.
The booking API was already correct: a machine booking clears the site and posts
income, a site booking posts none. Verified at 768x1024 and 375x812.