attr.grid now accepts two new tokens alongside fixed pt and "<n>%":
"auto"— sizes the column to the widest content in it."<n>fr"— shares the surplus left after fixed and auto columns, proportionally."1fr"and"2fr"split 1:2; pure-fr grids divide the row by fr factor.
Mix freely. ["120pt", "auto", "1fr"] pins the first column, sizes the second to its content, and lets the third absorb whatever's left. Resolution order is fixed → auto → fr; auto cells that overflow the row shrink toward min-content rather than wrapping.
Tables coordinate widths across rows. A table()'s header and every materialized data row resolve their auto/fr columns once across the union of their content, so column edges line up vertically instead of each row sizing itself in isolation.
A new optional row attribute, grid-id, extends that coordination across separate containers — the use case is totals() aligning with the table() above it. table() and totals() now stamp a deterministic grid-id derived from the shared cols array, so totals rows participate in the same group as the table whose columns they should align with. The Amount column lines up whether it's a fixed percentage, an auto sized to data (e.g. a Balance column in a bank statement), or anything in between.
totRow() (the building block behind totals()) was rewritten to span its label across every column except the last, leaving the value in the final column. Labels get all the room they need and never wrap into a narrow numeric column; the value column is what aligns with the table.
Six library templates were tightened to demonstrate the new tokens — invoice-compact, receipt-retail, quote-modern, statement-bank, shipping-label-standard, and report-standard — with defensive percentages replaced by auto/1fr where they were previously hiding worst-case data-width guesses.
The DSL skill file at /skills/pdf-template-author.md has the new tokens documented in the grid section. The /api/v1/preview and /api/v1/render pipelines pick this up automatically — no API changes.