A wrapping rule for the second cell sounds like a simple description-column fix. In a total row, however, that second cell can be an amount. This note follows the row structure behind a ledger readability change and shares an independent example.
Start with the request to keep an amount together
The historical work conversation includes a request about numbers falling onto another line and a ledger that felt too compressed. The final answer at that time describes adjustments to amount wrapping, width, spacing and right alignment. For this article I read the current local table renderer and styles. I did not reproduce the old screen review or resume the paused ERP application.
For someone checking a balance, a complete number is a unit of reading. Splitting its digits creates extra work. Preventing every cell from wrapping, however, lets a long description demand more horizontal space than it needs. The request therefore called for different rules for descriptions and amounts.
The existing table module already explains how to keep a wide table inside a local scrolling region. This article examines the cells within that region. Transaction rows, detail rows and total rows have different structures. The maker’s question is how to distinguish a description cell from an amount cell when those structures change.
Visual column position differs from child position
A normal row creates a record cell, a description cell and amount cells. Its second child is the description. A total row merges the first two visual columns into one header and places its first amount after that header. The amount begins in the third visual column, but it is the row’s second child cell.
A blanket td:nth-child(2) description rule can therefore select the first amount in a total row as well. A colspan changes the number of columns occupied by a cell; it does not create two child cells in the row. Treating these two coordinate systems as interchangeable makes the selector’s meaning unreliable across row shapes.
I am not presenting this as a new incident in which money was stored incorrectly. The finding comes from the inspected structures and the independent synthetic example. The second child is memo in an ordinary row and money in a summary row. That is a concrete counterexample to assuming one positional selector always identifies one business role.
The source scopes the description exception to row types
The later corrective rules in the inspected stylesheet give the amount table’s cells unbroken text and right alignment, then restore wrapping only for the second cell of transaction and detail rows. They do not apply that description exception to every total row. The accompanying source comment explicitly includes the first amount after a merged total header.
Reading the renderer explains why that scope matters. The regular ledger places three amounts after the merged header. The combined historical/current ledger places several movement fields and a balance after it. A rule based on only the last few cells would not describe every row shape equally well. The row types and the intended numeric region need to be understood together.
The source does not annotate every cell with a semantic data attribute. It combines row type and position. In the shared example I developed that decision into explicit data-kind="memo" and data-kind="money" markers. This makes the responsibility easier to inspect in another column layout. It is an independent example, not a change installed into the original ERP.
Width and amount formatting have separate responsibilities
The earlier part of the paper stylesheet contains fixed table layout and a shared long-word wrapping rule. Later corrections switch the amount table to automatic layout and specify wrapping exceptions. A screen-only section sets different minimum widths and spacing for the regular and combined ledgers. Declaration order and scope are part of understanding that intended correction.
Right alignment, a tabular-nums request, wrapping prevention and adequate column width are different controls. Alignment alone does not keep a number together; nowrap can also require a table wider than its viewport. Actual fonts and computed layout need rendered inspection. I do not turn the presence of these declarations into a claim that every environment has been visually verified.
The existing local scrolling boundary can be reused here. The new example retains that public CSS and adds role-specific amount and description rules. It does not hide the whole document’s overflow or abbreviate amounts. Its minimum table width is an illustrative starting point, not the original ERP’s width or a universal ledger specification.
A complete independent example includes a merged total row
The complete HTML below is a new synthetic example that reuses the public wrapper and CSS from the existing table module. It has two ordinary entries and a total header spanning two columns. Descriptions may wrap. Amounts request a single line through their role attribute, including the first amount after the merged header.
The numbers are predefined display strings. The example performs no calculation, rounding, server saving or real ledger reconciliation. Zero remains a string and is not silently converted into absence. Explaining this display rule did not require customer names, staff details or actual transaction records.
You can copy the code into a standalone HTML file. The inline example uses the same material. The existing module’s body and version remain unchanged. I have not registered the same scrolling component again under another name or added a separate ZIP. The reusable addition is the role annotation and summary-row example provided in this article.
Explore the implementation
Complete independent synthetic HTML; copy and adapt
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Keep amounts intact in summary rows</title><style>body{margin:0;padding:18px;font:16px/1.6 system-ui;color:#173d36}*{box-sizing:border-box}.comparison-block { min-width: 0; max-width: 100%; }
.comparison-scroll {
width: 100%;
min-width: 0;
max-width: 100%;
overflow-x: auto;
border: 1px solid #cbd2cd;
}
.comparison-scroll:focus-visible {
outline: 3px solid #2d6a51;
outline-offset: 3px;
}
.comparison-scroll table {
width: 100%;
min-width: 40rem;
border-collapse: collapse;
line-height: 1.6;
}
.comparison-scroll caption {
padding: 1rem;
text-align: left;
font-weight: 700;
}
.comparison-scroll :is(th, td) {
padding: 1rem;
border-bottom: 1px solid #dce0dd;
text-align: left;
vertical-align: top;
overflow-wrap: anywhere;
}
.comparison-scroll thead th { background: #edf2ee; }
/* If the parent is a grid, use minmax(0, 1fr) for its content track. */
/* Synthetic addition: cell roles remain meaningful after colspan. */
.money-example table { min-width: 48rem; }
.money-example [data-kind="money"] {
white-space: nowrap;
overflow-wrap: normal;
word-break: normal;
text-align: right;
font-variant-numeric: tabular-nums;
}
.money-example [data-kind="memo"] {
white-space: normal;
overflow-wrap: anywhere;
text-align: left;
}
.money-example .summary th { text-align: left; }
</style><section class="comparison-block money-example"><h1 id="money-title">Keep amounts intact in summary rows</h1><p id="money-hint">Synthetic display only. Scroll the table region to inspect every column.</p><div class="comparison-scroll" role="region" tabindex="0" aria-labelledby="money-title" aria-describedby="money-hint"><table><caption>Invented values, no business records</caption><thead><tr><th scope="col">Record</th><th scope="col">Details</th><th scope="col">Added</th><th scope="col">Applied</th><th scope="col">Balance</th></tr></thead><tbody><tr class="entry"><th scope="row">R-A</th><td data-kind="memo">The description may wrap onto multiple lines; amounts keep their own display rule.</td><td data-kind="money">1,234,567</td><td data-kind="money">0</td><td data-kind="money">1,234,567</td></tr><tr class="entry"><th scope="row">R-B</th><td data-kind="memo">The description may wrap onto multiple lines; amounts keep their own display rule.</td><td data-kind="money">0</td><td data-kind="money">34,567</td><td data-kind="money">1,200,000</td></tr><tr class="summary"><th scope="row" colspan="2">Total</th><td data-kind="money">1,234,567</td><td data-kind="money">34,567</td><td data-kind="money">1,200,000</td></tr></tbody></table></div><p>Predefined display strings; no calculation, saving or real ledger reconciliation.</p></section></html>Structural checks and rendered checks are different evidence
A parser read the new HTML in both languages and checked nine conditions per language, 18 in total. There are five column headers, and every body row occupies five columns after expanding colspan. The ordinary and total rows have different roles at their second child. The first summary amount retains its money marker. Complete amount strings and zero were also compared.
The checks cover unique title/hint identifiers and region references, explicit role styling instead of a positional selector, and the absence of scripts, forms and external destinations. They inspect the actual new HTML structure and CSS declarations. They do not execute a CSS layout engine, the original React tests or a browser.
The source also has separate print rules. A screen width adjustment does not establish that paper, PNG or PDF output fits correctly. A real integration should inspect long descriptions, large amounts, negative notation, increased text size, summary and combined rows, and the output medium. These are follow-up review conditions rather than completed rendering checks in this run.
Read row roles before changing the column count
When applying this to another ledger, inspect more than one transaction row. Record how opening balances, daily totals, monthly totals, grand totals and detail rows create or merge their cells. Assign description and amount roles, then decide the minimum width and scrolling boundary. Also check that the presentation change leaves calculation values and stored fields untouched.
Reading the row structure provides a more useful explanation than simply saying that the columns were widened. Position two and description are equivalent in some rows and different in others. Keeping that distinction explicit gives the next maintainer an assumption to revisit when another column is introduced.
Use the existing table module for the outer scrolling region, caption and header structure, and the example here for summary-cell roles. Converting an editable table into cards belongs to the separate single-input module. A readable ledger depends on preserving both its business values and the structure through which people inspect them.