Reference
Block elements
Structural elements. Use these anywhere a document, page, container, or table cell expects content — they stack, nest, and paginate.
<text>
blockA paragraph of styled text that wraps to the available width and paginates by line.
| Attribute | Values | Default | Description |
|---|---|---|---|
font |
sans | serif | <face> | <standard> | sans | Font family: the embedded built-ins sans/serif, a <font-face>/<google-font> name, or a non-embedded standard PDF font (helvetica, times, courier, symbol, zapfdingbats). |
size |
length | 12 | Font size. |
bold |
true | false | false | Bold weight. |
italic |
true | false | false | Italic. |
align |
left | center | right | justify | left | Aligns lines within the block's own width; justify stretches every line but the last. The block fills wider than its text only when given a width or a stretching parent. |
color |
color | black | Text color. |
paragraph-spacing |
length | 0 | Extra vertical gap opened below each <p> paragraph break. |
Inline markup nests freely mid-paragraph: <b>, <i>, <u>, <s>, <font color size>, <a href>, <br/>, <p/> (paragraph break — see paragraph-spacing), <field name> (a page-counter placeholder), and <inline> (an inline-block — set any element in the flow).
align positions lines within the block's own box, which is as wide as its
widest line. So align="right" in a shrink-to-fit row aligns the lines relative
to each other, not to the row's right edge — to push the whole block to an edge,
give it a width (style:width) or a stretching parent (an <expander/> beside it,
a cross="stretch" column). A table cell or the full-width page column already
provides that box, so alignment fills there.
<text font="serif" size="14" bold="true" align="center">
The <i>quick</i> brown fox<br/>
jumps over the <font color="#b31d28">lazy</font> dog.
</text><rect>
blockA solid filled rectangle. Useful as a background, swatch, or block.
| Attribute | Values | Default | Description |
|---|---|---|---|
width |
length | 0 | Box width. |
height |
length | 0 | Box height. |
fill |
color | black | Fill color. |
<rect width="120px" height="40px" fill="#3366cc" /><line>
blockAn axis-aligned rule for dividers and separators, solid or dashed.
| Attribute | Values | Default | Description |
|---|---|---|---|
direction |
horizontal | vertical | horizontal | Axis the line runs along. |
length |
length | fill | Fixed extent; omitted, it fills the offered space. |
stroke-width |
length | 1 | Stroke width (same name as on circle). |
stroke |
color | black | Stroke color (same name as on circle). |
dash |
length | 0 | On/off run length for a dashed line; 0 is solid. |
A bare <line/> in a stretched column is a full-width divider. Drawn as a stroke
(not a filled rect), so it can dash. stroke / stroke-width match <circle>,
so the outline vocabulary is the same across both shapes.
<vertical gap="8px" cross="stretch">
<text bold="true">Section</text>
<line stroke-width="2px" stroke="#c4341f" />
<text>Body below the rule.</text>
<line stroke-width="1px" stroke="#999999" dash="3px" />
</vertical><circle>
blockA filled and/or stroked ellipse. radius gives a circle; width/height an ellipse.
| Attribute | Values | Default | Description |
|---|---|---|---|
radius |
length | 0 | Circle radius (sets both width and height). |
width |
length | — | Ellipse width (overrides radius). |
height |
length | — | Ellipse height (overrides radius). |
fill |
color | black* | Fill color. *Defaults to black only if no stroke is set. |
stroke |
color | — | Outline color (drawn inside the box). |
stroke-width |
length | 1 | Outline width. |
With neither fill nor stroke, a circle defaults to a solid black disc.
<horizontal gap="14px" cross="center">
<circle radius="20px" fill="#2255cc" />
<circle radius="20px" stroke="#cc7a00" stroke-width="2px" />
<circle width="56px" height="28px" fill="#22aa55" />
</horizontal><image>
blockA bitmap (PNG/JPEG) from a local path or http(s) URL. Aspect ratio is preserved.
| Attribute | Values | Default | Description |
|---|---|---|---|
src |
path | URL | — | Required. File path or http(s) URL. |
width |
length | auto | Target width; height scales to match. |
height |
length | auto | Target height; width scales to match. |
One of width / height is enough — the other is derived from the image's
natural aspect ratio. The CLI reads that from the file; the browser has no
filesystem, so it resolves src as a URL (relative paths from the site root,
e.g. assets/press.jpg → /assets/press.jpg), pre-measures the image, and
hands the size to the layout. Give both only to deliberately distort.
<image src="assets/press.jpg" width="240px" /><spacer>
blockEmpty vertical whitespace.
| Attribute | Values | Default | Description |
|---|---|---|---|
height |
length | 0 | Amount of vertical space. |
<vertical>
<rect width="160px" height="16px" fill="#1b1a17" />
<spacer height="24px" />
<rect width="160px" height="16px" fill="#c4341f" />
</vertical><vertical>
blockStacks its children top to bottom, paginating by child. The page body is a vertical internally.
| Attribute | Values | Default | Description |
|---|---|---|---|
gap |
length [length] | 0 | Space between children. One value sets both axes; two are (horizontal, vertical). |
main |
start … space-evenly | start | Main-axis (vertical) distribution: start, center, end, space-between, space-around, space-evenly. |
cross |
start | center | end | stretch | start | Cross-axis alignment; stretch fills the width. |
Any child may carry flex="n" to grow into leftover space.
<vertical gap="6px" cross="stretch" main="start"
style:min-height="170px" style:background="#faf6ed" style:padding="8px">
<text style:background="#efe9db" style:padding="6px">First line</text>
<text style:background="#e7e0d0" style:padding="6px">Second line</text>
</vertical><horizontal>
blockLays children left to right; a row of rigid children wraps to new lines when it overflows the width.
| Attribute | Values | Default | Description |
|---|---|---|---|
gap |
length [length] | 0 | Between children, and between wrapped lines (2nd value). |
main |
start … space-evenly | start | Main-axis (horizontal) distribution: start, center, end, space-between, space-around, space-evenly. |
cross |
start | center | end | stretch | start | Cross-axis alignment; stretch makes cells equal height. |
Equal columns: give children flex="1". <expander/> is a contentless spring.
<horizontal gap="12px" cross="stretch">
<vertical flex="1" style:background="#f0ece1" style:padding="10px">
<text>Column one</text>
</vertical>
<vertical flex="1" style:background="#e7e0d0" style:padding="10px">
<text>Column two</text>
</vertical>
</horizontal><stack>
blockLayers its children over each other in the same box; the last child is on top.
No attributes.
Children are anchored at the top-left and each is offered the full space; the
stack shrink-wraps to the largest layer. When the content overruns the page,
each layer paginates independently — its remainder continues on the next page in
the same z-position — so a short background layer paints only on the first page.
A background that must repeat on every page belongs in <layout>, not here.
<stack>
<rect width="220px" height="56px" fill="#1b1a17" />
<padding all="16px"><text color="white" size="16">Overlaid label</text></padding>
</stack><box>
blockA background + border + padding container around block-flow content.
| Attribute | Values | Default | Description |
|---|---|---|---|
background |
color | — | Fill behind the content. |
border |
1–4 lengths | 0 | Border widths (CSS shorthand). |
border-color |
color | black | Border color. |
radius |
length | 0 | Rounded corner radius. |
padding |
1–4 lengths | 0 | Inner padding (CSS shorthand). |
width |
length | — | Fixed box width. |
height |
length | — | Fixed box height. |
Sugar over the same machinery the style: box model builds — richer effects
(shadows, per-side borders, clipping) are still available via style: on the
same <box>.
A <box> collapses its content like any container: several children stack as a
column, a single child is used as-is, and bare text is wrapped as a paragraph —
so <box padding="10px">Just text</box> needs no inner <text>.
<box background="#f3f1ea" border="1px" border-color="#c9c4b4" radius="8px" padding="10px">
<text>A box gives the box model a home element.</text>
</box><padding>
blockInsets a single child. For most spacing, prefer style:padding / style:margin.
| Attribute | Values | Default | Description |
|---|---|---|---|
all |
length | 0 | CSS 1–4 length shorthand for every side (e.g. 8px or 8px 16px). Same grammar as box/style:padding. |
top / right / bottom / left |
length | all | Override an individual side. |
<padding all="8px" left="32px">
<text>Indented more on the left.</text>
</padding><table>
blockA grid with repeating headers, fixed or fractional columns, borders, and zebra striping. Cells hold any elements.
| Attribute | Values | Default | Description |
|---|---|---|---|
columns |
spec list | equal `*` | Per-column widths: a length (100px) is fixed; */2* is a weighted fraction of the leftover; auto sizes to the column's content. Omitted (or any column left unspecified) means an equal * fraction. auto columns are served before fractions, so auto 1* hugs the first column and fills the second. |
border |
spec | hairline grid | Space-separated: a length (thickness), a color, and which lines — grid (all, default), rows, cols, outer, or none. e.g. 0.5pt #ccc rows outer. |
border-color |
color | grey | Grid line color, when the border spec names none. |
cell-padding |
length | 4 | Inset inside every cell. |
edge-padding |
length | 0 | Extra inset between the table's left/right edge and the outer columns' content. Backgrounds and borders still reach the edge — only the text moves in. |
stripe |
color | none | Zebra fill for alternating body rows. |
header-border |
true | false | true | Draw the line between the header and the body. Off lets a full-bleed header run into the first body row. |
font / size / bold / italic / color / background |
— | — | Per-<header>/<row>/<cell>: text style (font, size, weight, slant, color) that cascades to the cells' content, and a background fill. align stays per-cell. |
Sub-tags: <header> (rows repeated on every page), <row>, and <cell> — cells
take colspan, rowspan, valign (top | middle/center | bottom), and
background. A <header> or <row> carries the text style for its cells —
font, size, bold, italic, color, and a background band — and those
cascade to every cell's content (cell beats row beats the document default),
reaching nested <text> and inline runs that don't set their own; align stays
per-cell, since columns differ. A <header> accepts its cells two ways: wrap them
in a <row> (use this for a multi-row header), or — the common case — list
<cell>s directly inside <header>, and it reads as a single styled row (the
example below uses this shorthand).
A single row taller than the page splits across pages; rowspan cells group their rows into a section that moves together.
Column widths come from the columns spec. A fixed length (100px) claims
its size. An auto column is measured and sized to its content — the widest
cell, shrinking toward its longest word only if the row would otherwise overflow.
A fraction (*, 2*) splits whatever width is left after the fixed and auto
columns, by weight. auto is served before fractions, so columns="auto 1*" is
the common "label hugs, body fills" pair; a table of only auto columns shrinks
to fit its content. With no columns attribute — or for any column the spec
doesn't reach — every such column is an equal * fraction, so the grid divides
the full width evenly. (Content sizing reads non-spanning cells; a colspan cell
lays out into whatever its columns resolve to.)
edge-padding gives the content breathing room at the table's left and right
edges without pulling the backgrounds in: it insets only the leftmost cell's left
and the rightmost cell's right content, so a full-width header fill or row stripe
still reaches the page edge while the text sits in from it. (cell-padding insets
every cell on all sides; edge-padding is the extra outer gutter.)
The border spec controls which lines draw. List a thickness, a color, and any
of grid (all lines, the default), rows (horizontal lines between rows), cols
(vertical lines between columns), outer (just the frame), or none — naming one
turns the rest off. So border="0.5pt #ccc rows" draws only row separators, and
border="0.5pt #ccc rows outer" adds the frame. (border="0.5pt" with a separate
border-color still works.) Row backgrounds and stripes fill edge-to-edge and run
continuously between rows — the lines and frame paint over them — so turning a line
off never leaves a seam. header-border="false" drops just the header/body line,
letting a colored header run straight into the body.
style: works at three levels. The table and each cell are real boxes, so
they take the full box model (style:background, padding, border, radius,
box-shadow, …) — the table around the whole grid, a cell around its content. A
row is painted as a band: it takes the box decorations (background, border,
radius, box-shadow), vertical padding (which grows the band and insets its
content), and margin — vertical margin opens transparent gaps above/below the
band; horizontal margin indents the row into a detached card, stealing the width
from the fractional columns first, then the trailing ones. (A margined row leaves
the table's grid lines and shows its own style:border instead.) Horizontal
padding is still ignored on a row — its cells sit in the shared columns; use
cell-padding or a horizontal margin instead. Row margin applies to ordinary,
non-rowspan rows.
Bare cell text resolves <text> defaults: a <defaults><text font="…"/></defaults>
applies to <cell>foo</cell> just as it would to a standalone <text>.
<table columns="2* 1* 80px" border="0.5px" cell-padding="6px" stripe="#f3eee2">
<header background="#1b1a17" color="#fff" bold="true">
<cell>Name</cell><cell>Role</cell><cell align="right">Age</cell>
</header>
<row><cell>Ada</cell><cell>Engineer</cell><cell align="right">36</cell></row>
<row><cell>Linus</cell><cell>Maintainer</cell><cell align="right">54</cell></row>
<row><cell colspan="3" valign="middle">Spanning footer</cell></row>
</table><list>
blockA bulleted or numbered list; each
| Attribute | Values | Default | Description |
|---|---|---|---|
marker |
bullet/disc | circle | square | dash | decimal | lower-alpha | upper-alpha | none | <literal> | bullet | Marker glyph or numbering. bullet/disc is a filled dot, circle a hollow one, square a filled square; any other string is used verbatim as the marker. |
start |
number | 1 | First number for ordered markers. |
gap |
length | 4 | Vertical space between items. |
indent |
length | 18 | Width of the marker gutter. |
marker-color |
color | text color | Color of the markers. |
font |
sans | serif | <family> | inherited | Font family for item text and markers. |
size |
length | inherited | Font size for item text and markers. |
bold |
true | false | inherited | Bolds item text and markers. |
italic |
true | false | inherited | Italicizes item text and markers. |
color |
color | black | Text color for items (and the marker fallback when marker-color is unset). |
Pagination is by whole item; an <item> taller than the page is dropped (like an
over-tall table row). Numbering stays continuous across a page break.
<list marker="decimal" gap="3px">
<item>First ordered item</item>
<item>A longer item that wraps onto a second line</item>
<item>Third</item>
</list><expander>
blockA contentless spring that absorbs leftover main-axis space, pushing what follows to the far edge.
| Attribute | Values | Default | Description |
|---|---|---|---|
weight |
number | 1 | Share of free space relative to sibling springs. |
Same idea as flex on an empty element; any child can carry flex="n" directly.
<horizontal cross="center">
<text bold="true" size="16">Title</text>
<expander/>
<text color="#8a8678">page 1</text>
</horizontal>