8. Templates

Built-in types — each a bundle over a primitive base, named because the pattern is common. Every rectangular template is a bundle over |block|; the non-rect primitives (SPEC 7) stand on their own. A template’s defaults are the low tier of the cascade (SPEC 4) — every value here is overridable.

TemplateBaseDefaultsFor
|box||block|fill: --fill; stroke: --stroke; stroke-width: 2; radius: 8; padding: 20The default node — a rounded, framed card.
|rect||box|radius: 0A sharp-cornered box.
|group||block|stroke: --group-stroke; stroke-style: dashed; stroke-width: 1; fill: --group-fill; radius: 8; padding: 20Dashed frame for a caption + children.
|caption||block|pin: top left; translate: 0 -20; color: --caption-color; font-size: 12∕15 of inherited ([SPEC 6](06-paint-stroke-text.md#6-paint-stroke--text)); font-weight: --caption-font-weightA title, pinned just above the group’s top-left corner.
|footnote||caption|pin: bottom; translate: 0 19; color: --footer-colorA caption flipped to a shape’s bottom edge — a centred, muted footnote.
|sheet-caption||caption|translate: 10 10; font-size: 16∕15 of inherited; font-weight: semiboldA block title seated inside its frame’s top-left corner — what a schematic scope’s label lowers to (SPEC 16.6).
|badge||block|pin: top right; translate: 6 -6; radius: 8; padding: 2 6; shadow: 2 3 3; fill: --accent; color: --accent-text; font-size: 11; font-weight: normalCorner pill — nudged out over the top-right corner, grows nothing.
|row||block|direction: rowFrameless wrapper — children in a row.
|column||block|direction: columnFrameless wrapper — children in a column.
|grid||block|layout: gridFrameless grid (needs columns).
|sign||icon|width: 64; height: 64; padding: 4; stroke-width: 2; fit: containA larger icon as a stand-alone node, with room for a short label; fit: contain fills the box (unlike a bare |icon|).
|table||group|layout: grid; align: stretch; justify: stretch; gap: 1; gap-fill: --stroke; padding: 0; fill: none; stroke: --stroke; stroke-width: 2; stroke-style: solid; font-size: 14; font-weight: normal; scale: 1Ruled grid (see below).
|cell||block|padding: 4 8A table cell — a frameless |block| carrying the text-to-gutter inset (the mechanism: Tables, below).
|header||cell|fill: --header-fill; font-weight: semiboldA header cell — a filled, semibold band (a |table|’s first row; an |entity|’s title spans them).
|footer||cell|color: --footer-colorA footer cell — muted text; opt-in on the last row.
|entity||table|columns: auto, autoAn ER / database entity — a titled field list, rows left-aligned (see below).
|topic||block|fill: --fill; stroke: --stroke; stroke-width: 2; radius: 8; padding: 8 14A tree’s structural node — topic nesting is the hierarchy, anything else in its [ ] is the topic’s own content (SPEC 12); custom structural types derive from it (|person::topic|). Tree-only.
|mindmap||topic|layout: tree; direction: bilateral; routing: natural — plus the palette walk, the depth ramp, and max-width: 160 on topics (see below)A mindmap — the node is the visible root topic, its [ ] topics the first-level branches (SPEC 12).
|note||block|fill: --fill; stroke: --stroke; padding: 20; scale: 1A note — the folded-corner callout card, one type in every layout (see below).
|balloon||oval|width: 16; fill: --fill; stroke: --stroke; font-size: 11; scale: 1An item balloon — the numbered circle an assembly leaders to a part (SPEC 15.8).
|stack||block|layout: stack; padding: 0The datum container (SPEC 12) — children place their origin on it instead of flowing.
|drawing||block|layout: drawing; padding: 0An engineering drawing — geometry on a datum, measured annotations; scale: is its drafting ratio, default 1 (SPEC 15).
|hole||oval|fill: --bg; stroke: --stroke-darkwidth: required, the diameterA round hole — punches by paint order, draws its own centre marks (SPEC 15.4).
|centerline||line|stroke-style: center; stroke: --stroke-light; stroke-width: 1; fill: none — needs points:The dash-dot axis / symmetry line (SPEC 15.7).
|pitch-circle||oval|stroke-style: center; stroke: --stroke-light; stroke-width: 1; fill: nonewidth: required, the diameterThe dash-dot bolt circle; round, so a (o) reads its PCD (SPEC 15.7).
|breakline||line|stroke: --stroke-light; stroke-width: 1; fill: none — needs points:A break cut’s edge — the thin jogged line a break: generates (SPEC 15.3); manual use is free.
|halo||line|generated chrome — halo-margin each sideAn annotation line’s crossing knockout over geometry (SPEC 15.7); |halo| { … } restyles or removes them scope-wide.
|threadline||line|stroke: --stroke-light; stroke-width: 1; fill: none — generated chromeA thread’s ISO 6410 thin line — the minor/major run and the ¾ arc a thread: generates (SPEC 15.3, SPEC 15.4).
|hidden||sketch|stroke-style: dashed; stroke: --stroke-dark; stroke-width: 1; fill: none — needs draw:Hidden edges — interior geometry on its own dashed child, per the one-node-one-stroke-style law (SPEC 15.7).
|shoulder||line|stroke: --stroke-dark; stroke-width: 2; fill: none — needs points:A turned part’s shoulder line — the geometry-weight edge a revolve: generates at every sharp diameter change (SPEC 15.3); manual use is free.
|plane||line|stroke-style: center; stroke: --stroke-light; stroke-width: 1; fill: noneThe section-plane line on the source view — its label the section letter; at: stations it, facing: turns its arrows; a |drawing| { of: } sections it (SPEC 15.8).
|magnifier||oval|stroke: --stroke-light; stroke-width: 1; fill: nonewidth: required, the region diameterThe detail marker — rings a region on the source view, its label the detail letter at the rim; a |drawing| { of: } details it (SPEC 15.8).
|projection||line|stroke: --stroke-light; stroke-width: 1; fill: none — needs points:A projection construction line — the straight thin line a sheet’s cross-view link generates (SPEC 15.8); manual use is free.
|surface-finish||block|symbol: basic; stroke: --stroke-dark; stroke-width: 1; fill: none; font-size: 12; scale: 1The ISO 1302 surface-texture symbol — its label the textual indication, symbol: the vee variant; drawing-scope (SPEC 15.9).
|feature-control||block|stroke: --stroke-dark; stroke-width: 1; fill: --bg; font-size: 12; scale: 1The GD&T frame — characteristic, tolerance, datums in ruled compartments; rows via |control|; drawing-scope (SPEC 15.9).
|control||block|One frame row — its label the characteristic; a |feature-control| child only (SPEC 15.9).
|datum||block|stroke: --stroke-dark; stroke-width: 1; fill: --bg; font-size: 12; scale: 1The framed datum letter as a node — its label the letter, an identity like >-’s; drawing-scope (SPEC 15.7, SPEC 15.9).
|page||block|layout: flow; fill: --bgsheet: a4 unless sized; direction by orientationAn ISO 5457 drawing sheet — mm dimensions via sheet:; px per mm from the root density:; frame, zones, and centring marks as generated chrome (SPEC 15.8).
|title-block||table|font-size: 14; font-weight: semibold; stroke-width: 1The ISO 7200 title block — a table the |page| seats flush inside its frame’s bottom-right corner. Field properties (title, drawing-number, revision, date, sheet-number, author, …) build the standard grid, absent fields collapsing; its smart label is the title field; plain cells stay a fully custom block (SPEC 15.8).
|frame||rect|fill: none; stroke: --stroke; stroke-width: 2A sheet’s frame — the thick border a |page| generates at the ISO margins (SPEC 15.8).
|field||block|font-size: 12; font-weight: normal; color: --footer-colorA title-block field’s caption, over its value — quieter in size, weight, and tone (SPEC 15.8).
|zone||block|font-size: 11; color: --stroke-lightA zone reference label (1, 2… / A, B…) a |page| generates in the margin band (SPEC 15.8).
|tick||line|stroke: --stroke; stroke-width: 1; fill: none — needs points:A zone divider / centring mark a |page| generates (SPEC 15.8).
|schematic||block|layout: schematicA circuit sheet’s scope (SPEC 16).
|component||block|fill: --component-fill; stroke: --component-stroke; stroke-width: 1.5; radius: 0; padding: 8; prefix: "U"The generic pin-bearing part — IC, module, relay; ref prefix U (SPEC 16.2).
|pin||block|name inside, number: outside, stub outward — no side: default (the bilateral split, SPEC 16.2)A component terminal — the wire lands on its stub tip.
|space||block|width: 20; height: 20 — one rail slot, span: N for NAn empty slot between a component’s pins (SPEC 16.2).
|label||block|shape: plain; font-size: 11; color: --label-inkThe net tag — text, a symbol (gnd, power, …), or both; its own terminal (SPEC 16.4).
|junction||oval|fill: --wire; stroke: none — generated chromeThe connection dot where ≥ 3 wire ends meet (SPEC 16.5).
|J||component|prefix: "J" — pins nameless, pins: N generates them side: left (one column)The connector (SPEC 16.2).
|opamp||component|prefix: "U" — pins out inp inn; power pins hiddenThe amplifier triangle (SPEC 16.2).
the discretes|R| |C| |L| |D| |LED| |Q| |Y| |F| |FB| |SW| |BT| |V| |I| |M| |BZ| |TP||block|symbol-bodied, generated pins, symbol: variantsThe one/two/three-terminal parts; the type is the ref family (SPEC 16.3).
|gnd| / |nc||label|symbol: gnd / symbol: ncBuilt-in ground / no-connect defines (SPEC 16.4).
|floorplan||drawing|layout: floorplanAn architectural floor plan — the drawing engine in a dialect, so |drawing|-scoped rules dress it too (SPEC 15.11).
|wall||sketch|fill: --stroke-dark; stroke: nonedraw: traces the centreline; thickness: inherited (200 mm)A wall run — offset to a solid (poché) outline at lowering; openings ride its [ ] (SPEC 15.11).
|partition||wall|thickness: 100 (mm — the true-size law, SPEC 15.11)The thinner interior wall — a define, nothing more.
|door||block|on: required; width: 900 (mm); hinge: start; swing: leftA wall opening — gap + leaf + swing arc; symbol: single / double / sliding (SPEC 15.11).
|window||block|on: required; width: 1200 (mm)A glazed wall opening — gap + sill lines (SPEC 15.11).
the opening / stair chrome|door-leaf| |door-swing| |window-sill| |stair-tread| |stair-arrow||line|stroke: --stroke-light; stroke-width: 1; fill: none — generated chromeWhat an opening and a flight draw: the leaf (a slider’s panels too), its quarter swing arc, a window’s sill pair, the treads and the up arrow; |door-swing| { … } restyles or removes them scope-wide (SPEC 15.11).
the fixtures|bed| |sofa| |dining| |bath| |appliance| |stairs||block|stroke: --stroke-dark; stroke-width: 1; fill: --bg — symbol-bodied, true-size mm defaults; symbol: variants (|stairs| takes none — steps: N required)The furniture set — thin outline, masking what it overlaps (SPEC 15.11).

The bare |block| is the base everything rectangular builds on — frameless, yet a real box (id, class, children, wirable, positionable): what you reach for to wrap text that needs box behaviour.

Captions. Both caption templates are out-of-flow overlays — they never push the content, their place fixed by the template, not by where they sit among the children, so a row-laid group carries its title just the same. A group’s label is its caption (SPEC 3), so |group#panel| "Settings" [ … ] and |group#panel| [ |caption| "Settings" … ] are equal; |caption| { font-size: 16 } styles every caption without touching body text.

Notes. A |note| is the callout card — a filled block with a folded top-right corner. It is one type in every layout: in a sequence it binds to lifelines with place: (SPEC 13); in a drawing it places at the datum, usually wired by a leader (SPEC 15.7); in flow / grid it is an ordinary padded card. Built-in scoped rules — |sequence| |note| and |drawing| |note|, each { padding: 6 10; font-size: 13 } — keep it compact where convention expects; override them like any rule.

Topics & mindmaps. A |topic| is the tree’s structural node (SPEC 12), a compact card whose label is its centred text. |mindmap| is the visible root topic owning the scene — layout: tree; direction: bilateral; routing: natural — plus three deterministic garnishes, each lowered at desugar as ordinary generated rules (visible in lini desugar, overridable like any rule): the palette walk — each first-level branch takes the next hue (SPEC 10.2) in declaration order, red and grey skipped, and tints its subtree at the tiers (wash fill, deep stroke and branch wires, ink text; the root stays neutral, explicit paint wins, cross-links stay neutral, dark mode free); the depth ramp.lini-level-N rules size the tiers (root largest, level 1 medium, deeper small); and topic wrapmax-width: 160, so a long label wraps into a card instead of stretching an arm. A plain layout: tree carries none of these — org charts read monochrome.

Tables. A |table| is pure sugar over the bundle above — its 1px gap-fill gutters paint as hairline rules (SPEC 11). Each body cell wraps in a |cell|; |header| / |footer| build on it, so every cell — but not the caption, a plain |block| — carries the inset. Style all cells with |cell| { … }, or per table with |table| |cell| { … }. The table’s align: stretch; justify: stretch makes every cell fill its track — backgrounds fill and text has room. A table’s label is its caption.

Column alignment. align (↔) / justify (↕) on the table read per column (SPEC 12) and align the cells’ text: since the cells already fill, the table’s own align/justify are carried onto each cell — a start/end column’s cells wear a .lini-align-* / .lini-justify-* class — and a filled cell places its text at that edge (center is the default). So align: start, center, end reads three columns left / centre / right, header band and body alike.

A table’s first row becomes its header — each cell wrapped as a |header|, a filled semibold band; |table| |header| { font-weight: normal; fill: none } reverts it. A footer is opt-in: wrap a last-row cell in |footer|. Every cell is a box now — header/footer carry a fill; a body cell is a frameless |block| wrapping its text, so the padding rule and the column’s alignment reach it (SPEC 18).

|table#basket| {
  columns: 80, 140, 80;
} [
  "Fruit" "Quantity" "Notes"   // the header row — filled + bold
  "Apple" "12"       "fresh"
  "Mango" "3"        "ripe"
]
Fruit Quantity Notes Apple 12 fresh Mango 3 ripe

fmt knows the column count and pads the cells into aligned columns, so the flat form reads like the table it is. A cell that must be placed or linked is a box child (|cell| "X" for a padded cell, or |box| { cell: 2 1; … }); a cell that just needs a colour or weight can take its own style block ("Apple" { color: --red-ink }).

Entities. An |entity| is sugar over |table| (two auto columns) for an ER / database card: its label is its title — a |header| spanning every column, centred over left-aligned "field" "type" rows (an entity’s field rows read left by default; the title keeps its centred, full-span band). Add a column for a key gutter — { columns: auto, auto, auto } gives "PK"/"FK" "field" "type". In an entity (not a plain table) a |header| / |footer| cell spans the full width.

|entity#users| "Users" [ "id" "int"  "name" "varchar" ]
Users id int name varchar

Relationships are ordinary links with the ER cardinality operators (SPEC 9): users -< orders is one-to-many, a >-< b many-to-many, landing on the entity edge. To anchor a wire to one field, give that cell an id (|cell#user_id| "user_id") and link the path (orders.user_id -< users.id): the card’s cells tile, so the wire leaves the card at that field’s row rather than crossing the cells (ROUTING). Keys are plain content ("id" { font-weight: bold }); an entity adds no grammar.

Extend any template: |panel::group| { stroke: --accent }. Common nodes need no template:

ForWrite
Circle|oval| { width: 40 }
Database|cyl|
Arrow|line| { marker-end: arrow; points: 0 0, 50 0 }