On the Snick System a paragraph does not get a page; it gets a block, and a block is a measure — so many characters wide, so many lines tall, fixed by its span on the base grid and its step on the √φ scale. The concept plan scheduled a "copy sprint" to rewrite the client's voice into block-sized punches. This study builds the ruler that sprint would need, then turns the block into the editor: type into it and it tells you, as you go, whether the copy fits — and, for display type, whether the letters land on the grid line or merely near it.
Every cell is characters per line for a block of that span at that step, with the lines it holds in the default two rows underneath. Nothing here is assumed: the stage below is measured for its width and padding, and the average character width comes from the browser setting a sample sentence in the real Schibsted Grotesk at the real size. Resize the window and the ruler re-reads itself for the new edition. Greyed cells are dead measures — fewer than eight characters a line is a word, not a line.
Four of these blocks are editable — click into any of them and write. Each reports in its corner: how many lines the copy took of the lines its rows allow, how many characters are left on the last line, and a verdict. Fits is the aim. Loose means the last line is under a third full — a widow in a block that has no room for one. Row +1 means the copy needed more than its rows and the engine gave it the extra row (the v0.1.3 law: type never spills, it grows its row — but look at what happens to the neighbours). Collides means you widened a text block into another one. The bar along the bottom edge is the last line's fill. Widen a block or change its step with the controls; the script only ever writes numbers, and the stylesheet does the rest. The studio's own copy fits at the desktop pair and earns a loose in one block at each smaller pair — the editions recompose the blocks, and the same sentence has a different shape on each.
Write to the span, not to the page.
A block is a measure. Count characters, not words.
THE BLOCK REPORTS; IT NEVER REWRITES. YOUR COPY IS YOURS, WRONG LENGTH AND ALL.
Type never loses. When it needs a row, the row is given.
The concept plan's last technical note named two things "to watch, not lean on yet" — one of them text-box-trim, "for optically perfect block typography". A line of type carries leading above and below its letters; set a display word at the bottom of a block and its baseline floats a few pixels above the edge, its cap height a few pixels below the top of the padding. On a grid that is drawn to be counted, a few pixels is the difference between on the line and near it. The top row is untrimmed. The bottom row asks the browser to trim the line box to the cap height and the alphabetic baseline. The purple rules are the grid's row lines; the table is measured from layout, not from the stylesheet.
Snick
Type
Grid
Snick
Type
Grid
Second session with the draw, first with it as charter cadence. Five sentences from the archive, seeded by the date. The queue said Manifests or this; the draw did not hesitate:
Two to watch, not lean on yet: anchor positioning for annotation callouts, text-box-trim for optically perfect block typography.the plan's own "not yet" · answered: Study C leans on it, measures it, and rules on whether the wait is over
P2 Astro pipeline: blocks, scores, kind inference, editions; deploy loop to new.lxdintegral.com 2 sessionsthe client build's schedule · considered, not answered here; noted that Study A's table is what a "kind inference" step would consume
The public pages ship CSS and content; the rare interactive block (a dashboard widget, the grid clock) hydrates alone.answered by construction: this page is CSS and copy; one script hydrates the editor and the two measurements, and every word reads without it
It describes, exactly, what a block does when it lands on a grid line.the spec's promise about blocks · turned on the type: what does a letter do when it lands on a grid line? Study C, to a tenth of a pixel
Accessibility is a positioning asset, not a constraint.answered: the editable blocks are real textboxes in reading order, the verdicts are live regions, and the accessibility tree was read back to check
draw.js| Constant | Value | Why |
|---|---|---|
| measure | stage × span ÷ base − 2 × pad | read from the live stage and its padding, never from the tokens; the ruler is only as honest as its width |
| character width | canvas measureText(sample) ÷ 92 | a 92-character sample sentence set in the block's own font, weight and size; letters, not ems |
| lines | distinct tops of the range's client rects | the browser's own line breaks, grouped within 2px; no guessing from height |
| rows needed | ⌈(padding + paragraph) ÷ row⌉ | the block's own need, so a row that grew for a neighbour is not blamed on this block |
| loose | last line < 35% and lines > 1 | a widow threshold for blocks; one word on a line is loose, one third of a line is not |
| collides | bounding boxes overlap by > 1px | only against other text blocks — overlapping an empty field is the plane 0 privilege, not a fault |
| span clamp | 1 ≤ s ≤ base − c + 1 | re-applied at every edition; no block may leave the union grid, whatever it was told at a wider one |
| steps | s1–s8 · 1.55 / 1.25 / 1.1 / 1.02 | line-height per step in the score, not the script: body breathes, display packs |
| S edition | s5–s8 drop one step | the phone's measure is a third of the desktop's and the type cannot be; the readout reports the size actually set |
| report | 350 ms after the last keystroke | the live region speaks when you pause, never per key |
| trim | trim-both · cap · alphabetic | line box cut to cap height above and baseline below; descenders hang, as in metal |
| baseline | text rect top + font ascent | the font's own ascent from the canvas; validated because the trimmed row measures zero with it |