6. Paint, Stroke & Text

The visual vocabulary shared by every node. These are ordinary properties — the full list, with value shapes and defaults, is the Property Ledger; the colour system they draw on is SPEC 10. This section is the behaviour.

Paint

fill paints a body, color a label. fill is a closed shape’s interior (and, on text, an alias for its fill); color sets text colour for a subtree and cascades through the SVG via native currentColor — set it on a container to recolour every descendant’s text that doesn’t override. opacity (0–1) fades a node whole. fill, stroke, and gap-fill each accept a gradient as well as a flat colour (SPEC 10).

Stroke

One stroke role paints a shape’s outline and a link’s wire alikestroke the colour, stroke-width the thickness (markers scale with it), stroke-style the dash pattern (solid / dashed / dotted, plus the drafting center / phantom on shapes and |line|s and wavy on links — SPEC 7). There is no parallel link-* family: a .class carrying stroke dresses whichever wears it, node or link (SPEC 9). A closed primitive’s default outline is --stroke at width 2; a |group| softens to width 1.

Text

The text family — font-family, font-size, font-weight, font-style, text-transform, text-decoration, letter-spacing, line-spacing, and colorinherits: nearest ancestor wins, like CSS. Set it on a containing box (or the root) and it cascades down, or on a string’s own block ("x" { font-weight: bold }) for that one text node. Body text defaults to font-size 15, font-weight 500. Chrome text scales with the body: a caption reads 12∕15 and a link label 11∕15 of the inherited font-size — 12 and 11 at the default — so one font-size: scales the whole scene; an explicit font-size on either (|caption| { }, |-| { }, a class, an own block) is absolute. (A drawing’s annotation text stays the sheet convention, 12 — SPEC 15.1.)

Two bundled families (both SIL OFL 1.1) carry the metrics (SPEC 5): Google Sans, the proportional default, and Google Sans Code, the mono one declaration away (font-family: "Google Sans Code") — four static roman weights each. A font-family override changes only the emitted name: measurement stays by kind (mono vs proportional), so a runtime CSS restyle keeps the compiled layout box. font-weight takes normal | medium | semibold | bold | 400 | 500 | 600 | 700 (normal = 400, bold = 700; arbitrary 100–900 is deferred — SPEC 24); measurement reads the resolved weight (mono advances are weight-invariant). How fonts leave the compiler — names, embedded, outlined — is SPEC 18’s three output modes.

Line alignment rides the packing knob — there is no text-align. A text leaf’s lines — wrapped (SPEC 5) or authored \n lines — align per its nearest container box’s horizontal packing knob: justify in a row (so, by default — SPEC 11), align in a column or grid context, mapped start / center / end (stretch / evenly / origin read as center). The knob reaches the lines even when the box has no slack to move children; every box is a container, so the box holding the text decides, and the default is center everywhere. Split intents wrap the text in its own |block| { justify: … } — the table rule (SPEC 12) generalised to every box, which is why there is no second text-align knob.

Two kinds of text property, split by whether they touch layout:

  • Bakedletter-spacing, line-spacing, font-size, and text-transform — changes layout (the text box grows to fit the wider glyphs, the taller block, the capitals) and compiles into the glyph and line positions — text-transform into the text itself, measured as it will draw — never emitted as a style (SPEC 1). letter-spacing / line-spacing default to 0, so text is unaffected until set.
  • Live CSSfont-style, text-decoration, text-shadow — does not touch layout: it rides the class / <g> / .lini rule and a host page can override it. Set any in the global block to style the whole scene.

For a global font-family / color, prefer the --lini-font-family / --lini-text-color variables (or the --theme CLI flag, SPEC 20) for an embeddable diagram — they stay live for a host page to re-theme, where a global property bakes its value into the .lini rule (SPEC 10, SPEC 18).