Text, icons & images
Text is content, not a shape — a bare string is a text node wherever it stands. Icons are Phosphor glyphs drawn as paths. Images embed.
A string is a node
{ direction: column; gap: 14; align: start; }
"Plain text stands on its own."
"Styled in place." { color: --rose-ink; font-weight: bold; }
"Two lines,\nwith a break." { font-style: italic; }
|box#card| { fill: --purple-wash; stroke: --purple-deep; } [
"A heading" { font-weight: semibold; font-size: 17; color: --purple-ink; }
"and a line of body text under it." { color: --purple-ink; }
]
Where the string stands is what it becomes:
- On its own — a free text node.
- Inside a shape’s
[ ]— that shape’s text. Several strings are several nodes, stacked, because a shape’s content flows as a column.
Either way it takes a style block of text properties — color, the font-*
family, letter-spacing, text-decoration, translate, rotate — and wears
classes like anything else.
Anything that needs a border, padding or an id wraps in a |block|: the
frameless box.
Wrapping
{
gap: 20; align: start;
|box| { max-width: 170; fill: --teal-wash; stroke: --teal-deep; color: --teal-ink; }
}
|box#a| "Ship the release notes to every customer who asked"
|box#b| "Rotate the signing keys before the audit window opens" { align: start; }
|box#c| "Archive dashboards nobody opened this quarter" { align: end; }
max-width caps a box’s automatic width, and the text wraps to honour it,
breaking at whitespace first. The wrapped size is the measured size, so those
three cards sit at their true heights rather than at a guess.
There is no text-align. Lines align by the box’s own packing knob — align
in a column box, justify in a row — which is why b and c above differ
without either one naming text.
Icons
{
gap: 26;
.tag { fill: --sky-wash; stroke: --sky-ink; color: --sky-ink; }
}
|icon| "bell"
|icon| "heart" { fill: --rose-wash; stroke: --rose-ink; }
|icon| "cloud" { fill: none; stroke: --sky-deep; }
|icon| "chat-circle" .tag [ "3" ]
|sign#docs| "folder-simple" .tag [ "Docs" ]
|icon| draws a Phosphor icon named by its label
— or by symbol: — as inline paths. No icon font, and only the glyphs a figure
actually uses are embedded.
It paints like a box:
fillis the soft body,strokethe line.fill: nonemakes it a single-tone line icon, ascloudis above.- It is a square that grows with its
[ ]text.
|sign| is the larger preset with room for a word, and it takes links like any
other node.
Icons make cards
{
layout: grid; columns: repeat(3); gap: 20;
|card::box| { padding: 16 20; }
|stat::block| { font-size: 22; font-weight: bold; }
|cap::block| { font-size: 12; color: --muted; letter-spacing: 1; }
}
|card| { fill: --rose-wash; stroke: --rose-deep; } [
|icon| "bell" { fill: --rose-wash; stroke: --rose-ink; }
|stat| "128" { color: --rose-ink; }
|cap| "ALERTS"
]
|card| { fill: --purple-wash; stroke: --purple-deep; } [
|badge| "!"
|icon| "lock" { fill: --purple-wash; stroke: --purple-ink; }
|stat| "24" { color: --purple-ink; }
|cap| "KEYS"
]
|card| { fill: --lime-wash; stroke: --lime-deep; } [
|icon| "users" { fill: --lime-wash; stroke: --lime-ink; }
|stat| "1.4k" { color: --lime-ink; }
|cap| "TEAM"
]
Nothing here says direction. A shape’s children stack as a column, so an
icon over a number over a caption is just three children in order.
The rest is the language you already have — a define per role, a class-free
{ } where one card differs, and a |badge| pinned to the middle card, which
is the same overlay the diagrams page pinned to a card.
That icon is one node type everywhere: the same |icon| is a sequence
participant’s glyph, or a tree topic’s decoration.
Images
|image#logo| { src: "assets/logo.svg"; width: 120; height: 60; }
|image#photo| { src: "https://example.com/site.png"; width: 320; height: 180; fit: cover; }
|image| needs src, width and height. What happens next depends on where
the source lives:
- A local path is read once and embedded, so the output stays
self-contained — an SVG asset as a nested, id-isolated
<svg>, a raster as a base64 data URI. - A URL passes through untouched.
fit: maps the picture into its box: auto letterboxes, and contain,
cover and stretch do what CSS says.
Go deeper
Statements & the label covers text content, paint, stroke & text the text family, and nodes icons and images.