Lay stack-and-program rows out as a grid

A log row is the stack on the left and the program still to run on the right, and .flex-spread got that with justify-content: space-between. Wrap a flex row, though, and the two spans stop being a row: as soon as the program no longer fits beside the stack it takes a full-width line of its own, left-aligned because a lone item on a flex line sits at the start, and the stack is left stranded on the line above. Nothing marks where one step ends and the next begins. Concat's if/then traces run long enough to hit this on every row. Give the pair a two-column grid instead. The stack column takes its max-content width so it only claims what it needs, the program gets the 1fr rest and stays flush right as before, and a long program now wraps inside its own column - so every row still starts with its stack, and the left edge is what marks a row start. overflow-wrap: break-word rather than anywhere, because anywhere lowers the column's min-content contribution to a single character: on a phone a long stack squeezed the program into a letter-per-line ladder. break-word keeps the minimum at one whole word, so the stack wraps instead. StackStep, Calc's log and Concat's log all render this shape, so all three move to .stack-step. .flex-spread stays for the rvrb status row. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

author
Marijn Besseling <njirambem@gmail.com> · 2026-09-12 19:37 UTC
commit
a4d46838a4d6a6f27cd5b08ca342594a23e2603f
parent
b3393efd63
tree
browse at this commit

4 files changed +20 -3

Blog/Components/Pages/Calc.razor.js +1 -1

@@ -106,7 +106,7 @@ function writeLog(stack, words) {
106 106 log_left.textContent += " <=="
107 107 }
108 108
109 - let log_row = h("div", {class: "flex-spread"}, [log_left, log_right]);
109 + let log_row = h("div", {class: "stack-step"}, [log_left, log_right]);
110 110
111 111 log.appendChild(log_row);
112 112 }

Blog/Components/Pages/Concat.razor.js +1 -1

@@ -222,7 +222,7 @@ function writeLog(stack, words) {
222 222 log_left.textContent += " <==";
223 223 }
224 224
225 - let log_row = h("div", {class: "flex-spread"}, [log_left, log_right]);
225 + let log_row = h("div", {class: "stack-step"}, [log_left, log_right]);
226 226
227 227 log.appendChild(log_row);
228 228 resolve();

Blog/Components/_Shared/StackStep.razor +1 -1

@@ -1,6 +1,6 @@
1 1 @* One line of a worked stack example: the stack on the left, the program left to run on the right. *@
2 2
3 -<div class="flex-spread">
3 +<div class="stack-step">
4 4 <span>@Stack</span>
5 5 <span>@Program</span>
6 6 </div>

Blog/wwwroot/app.css +17 -0

@@ -197,6 +197,23 @@ main {
197 197 justify-content: space-between;
198 198 }
199 199
200 +/* A stack on the left, the program left to run on the right (the log rows and
201 + the worked examples in the docs). A grid rather than a spread flex row, so a
202 + long program wraps inside its own column instead of taking a full-width line
203 + of its own and leaving its stack stranded on the line above. */
204 +.stack-step {
205 + display: grid;
206 + grid-template-columns: minmax(0, max-content) 1fr;
207 + column-gap: var(--s0);
208 +}
209 +
210 +/* break-word, not anywhere: it keeps the column's minimum at one whole word, so
211 + a long stack can never squeeze the program down to a letter per line. */
212 +.stack-step > :last-child {
213 + text-align: right;
214 + overflow-wrap: break-word;
215 +}
216 +
200 217 .row + .row {
201 218 margin-block-start: var(--s0);
202 219 }