Examples

72 diagrams, each shown with the source that produced it. Every render here was compiled from that source during this build.

Diagrams 27

Architecture

contains is a relation: a boundary that groups children and is itself connectable. Note the arrow from input targets the whole api group, while handler -> db crosses the boundary from a node inside it.

<circle><connect><contains><hexagon><parallelogram><rect>

Breakword

Long-word splitting. Text wraps at spaces, but a single word wider than its box would otherwise overflow; as a last resort it is split at character boundaries so it still fits (CSS overflow-wrap: break-word). The left card only needs space breaks; the right card has one very long word that gets chopped, so it runs to more lines and is the taller of the two. The row's align="stretch" hands that height to the shorter card as well, so the pair reads as a set rather than as two cards that happen to sit together.

<contains><row><text>

C4

Not one line of Python. <person>, <container> and <external> come from the shipped c4 library, which is Sauvignon source you can read with cat sauvignon/prelude/c4.svgn - and which itself defines all four in terms of one <c4-element>, since a component may instantiate another. This is the answer to "how much of the language is written in the language": vocabulary can be, geometry and algorithms cannot. A C4 box is a name, a bracketed kind and a description - composition, so it belongs in a library rather than the engine.

<column><connect><container><contains><external><import>

Chronology

Two timelines on one axis: the history of humanities computing above the line and Tolkien's books below it, from the "two timelines" slide of the Digital Tolkien course's first lecture. A dot is a moment (at), the bar a stretch (start/end); the callouts that would land on one another are moved into the nearest gap, or out to a second level, and their leaders keep them attached. Pinned light, because the colours are the author's and the callouts are written in them.

<chronology><data><record>

Circuit

a quantum circuit (Bell state: H then CNOT). Wires and the control line are arrowless connectors (arrow="none"); gates sit on the wires.

<circle><column><connect><define><pos><rect>

Classdiagram

The arrowhead carries the relationship. A hollow triangle is generalisation, a filled diamond is composition, a hollow one is aggregation, and an open head is a plain association - so none of these four edges needs a word on it to say which is which. The class box itself is not Python: it is a <define> in the shipped uml library, imported by name. Read it with cat sauvignon/prelude/uml.svgn — and copy it into this file under the same name if you want a different one. A local <define> wins.

<class><column><connect><import><row><text>

Components

A reusable component: a titled box with an "in" and "out" port. Parameterized by ${name} and ${accent} (accent has a default).

<connect><contains><define><rect><row><service>

Detour

Obstacle avoidance. A connector used to plough straight through whatever happened to sit between its two ends. Now the engine grows every other shape by a clearance margin, builds a visibility graph over the corners, and takes the shortest path across it, so a route turns only where it must. client to store has the cache in the way and goes around it; log to sink has clear air and stays perfectly straight. Pinning from-anchor or to-anchor opts out, for the cases where a line is meant to pass through what it crosses. The log pair also shows nudging: two connectors between the same two shapes would land on exactly the same line, so only the top one would be visible and the labels would stack. Routes that run along each other are fanned apart, and their ends put back on the shapes.

<column><connect><rect><row>

Erd

Crow's-foot notation: the head at each end states that end's cardinality, so "a customer places many orders, each order belongs to one customer" is drawn rather than written. arrow="both" gives both ends a head; head is the to end and tail the from end. from-label and to-label write the cardinality AT the end it describes, which one mid-edge label cannot do.

<column><connect><entity><import><row><text>

Flowchart

Shapes are element types now: the tag IS the mark. Layout (column/row) and connection stay orthogonal to shape. The two tinted boxes carry their colour as a CLASS rather than as an inline fill, so the tint can follow the colour scheme. Pinned inline colours can't: a pale fill stays pale in dark mode, while the label colour flips light to suit the dark background, and the text all but vanishes against it. Anything given a fixed fill needs a fixed foreground to match, or a rule per scheme like this.

<column><connect><diamond><ellipse><rect><row>

Frames

<actor><column><else><frame><message><note>

Homebase

Two layers of a scholarly edition, and the mapping between them. Drawn for HoMe Base (home.digitaltolkien.com), whose Text Type ribbon this reproduces: the chapter as one linear strip, each cell's width its share of the tokens, green where a primary text has been identified. Below it the document layer — the leaves themselves. Most are not transcribed, which is the point of showing them: the presentation layer is a thin selection over a much larger corpus. Where a leaf is transcribed, the ink sits in a text block inset from the edge, and a partial region shows a P-text starting or ending part-way down a page. P3 survives only as a fragment on one torn scrap. Three features of <isometric> do the work. flow="run" lays a contiguous strip whose widths are proportional weights, which is the only way to get a seamless ribbon: squares set side by side across the screen project to rhombi that meet at a point and leave gaps, so a run has to go along a plane axis. rows with flow="down" wraps the leaves down each column before moving right — fill them across instead and the links cross, because a wrapped sequence then backtracks past a whole column. And shape="line" fans one P-text to its many leaves from along its own length, so the fan shows where in the text each leaf picks up; the four-cornered prism that suits a one-to-one link is unreadable here.

<isometric><layer><link><rect><style>

Isometric

<isometric> arranges its children in a scene rather than on the page: each <layer> is a plane floating above the next, its contents lying in that plane, and <link> draws the prism joining an object on one plane to one below. The whole projection is a single matrix over each plane's own flat coordinates — x = u − v, y = (u + v) / 2 for the classic 2:1 isometric. It rides on one group per layer, so the rectangles and their labels are projected together; nothing here computes a sheared glyph by hand. Two things the engine works out that are easy to get wrong by hand. A square tile is twice as wide once projected, so spacing has to be reckoned in screen units — space by the tile's own side and they overlap while looking right in the source. And the planes are separated by the edges that actually meet, not by the box around a plane: that box is mostly the empty air beside a parallelogram, so spacing by it charges every layer for a whole diagonal of blank paper. The draw order is the other half: a prism passes behind the tile it hangs from and in front of the one it lands on, which reads as depth. The scene's own order (panels, edges, shapes, labels) cannot express that, so an <isometric> is a figure and owns the order of its parts.

<isometric><layer><link><rect>

Linkeddata

Bilbo as linked data: what he is, where he lives, when he was born, where he first appears and who his friend is. Each dot is placed by hand with at, where the LOD of the Rings slide has it, and carries its name beside it.

<circle><connect><stack><style>

Linkedlist

a list node: a two-cell box [ data | next ], with both cells exposed

<cell><circle><connect><define><rect><row>

Network

A <network> has no flow and no centre: it places the nodes so the distance between every pair on the page is as close as it can get to the number of edges between them. Drawn as a <graph> this would grow a hierarchy out of whichever service happened to be written first.

<connect><cylinder><network><rect><style>

Proportion

Percentage sizing: a width/height given as "42%" resolves against the parent's definite inner size on that axis (the same definiteness gate as grow and fr). The column fills the canvas width, the row stretches to it, and the segments take their share of that definite width, so they tile it exactly (42 + 28 + 18 + 12 = 100). Against an indefinite parent a % falls back to content. % applies in row / column / stack, and to a grid child against its own cell; grid TRACKS use fr instead.

<box><column><row><text>

Prose

Text min/max-content: a bare <text> mark now has a real min-content (its longest word) and max-content (one line). In a definite-width column that stretches it, it WRAPS to the column width and grows taller. It is the first element whose height depends on its resolved width, so the two-pass resolver computes the width, then the text reports its height.

<column><text>

Recipe

reproducing Bluefish's "Baking Recipe": a titled, green-bordered table of rows with LEFT-aligned text (the new text-align on marks).

<column><contains><define><item><rect><style>

Relations

Two independently-stacked columns, joined by a relation the layout tree cannot express: <align> centres the side column's first node on "validate", and a connector wires them together. Neither column knows about the other; the cross-cutting constraint does.

<align><column><connect><hexagon><rect><row>

Sankey

A Sankey is not boxes and arrows with thick lines. Its whole claim is CONSERVATION - a band's width is its value, and what arrives at a node leaves it - so the layout is computed from the values rather than drawn. Two bands of equal width are equal quantities wherever they appear, because one scale covers the diagram. Try changing a value: everything downstream re-thickens with it.

<data><record><sankey>

Sections

Styled <contains> titles: a boundary title now takes the same text styling as a mark (font-size, font-weight, color, font-family/style), so each section gets a prominent, colour-matched heading. Before, every title was the fixed default (13px grey). color= sets the title colour, fill= the panel; a bigger font-size also reserves the right title height.

<contains><rect><row>

Sequence

The one picture the ordinary machinery could not hold. Everywhere else a connector attaches to a SHAPE; here the second axis is time, and a message attaches to a point partway down a lifeline - a place no mark exists at. So the geometry is computed, as <isometric>'s is. Note the third message: it runs from Browser straight to Postgres, THROUGH the API lifeline. That is correct here and is exactly what the obstacle-avoiding router would have refused to do. A <note> takes a row of its own, so it lands between the messages it was written between rather than beside them.

<actor><message><note><sequence>

Styled

Re-theme the whole diagram by overriding the palette variables in ONE place; role classes (accent/good/warn) handle individual nodes. (A plain diagram with no <style> also adapts to dark mode automatically, via the built-in @media prefers-color-scheme rule.)

<column><connect><diamond><ellipse><rect><row>

Transformer

One of the LLM architecture cards from Sebastian Raschka's gallery, which is a good stress test because the whole genre is one picture: a trunk of boxes, a block that repeats, residuals that bypass the block's halves, and modules floated off to the side that expand a box the trunk only names. Nothing here is a diagram type. The trunk is a <column>; the repeated block is a <contains> in a <row> with a <brace>, which takes the block's height from align="stretch" rather than being told it; the residuals are <connect routing="orthogonal"> pinned to the right at both ends; the side modules are ordinary subtrees in a sibling column, tied to what they explain by a dashed <connect> and pulled level with it by <align>. The one thing worth writing down: an aside must not move the thing it annotates. Put the whole trunk in ONE column and the asides beside it, and the trunk stays internally centred however wide the asides get. Hang them off a <row> half way down instead and everything below that row re-centres on the wider canvas, which looks right until you notice the arrow into the first box has gone diagonal.

<align><brace><circle><column><connect><contains>

Tree

The org-chart look comes from pinning the sides: every edge leaves the parent's south and enters a child's north. Left free, an orthogonal edge leaves whichever side faces the child, so the outer two would come out the parent's flanks and into the children's sides. Pinning s→n makes them share one drop from the parent and fan out along a level — the T-junction bus every org chart is drawn with.

<column><connect><rect><row><style>

Treemap

A treemap's only hard constraint is that AREA be proportional to value, which leaves each rectangle's shape free. Slicing naively spends that freedom on slivers whose areas the eye cannot compare; squarifying spends it on keeping every cell near-square, which is what makes one readable. See site/content/algorithms for the argument.

<data><record><treemap>

Charts 28

Barchart

A <plot> is a coordinate frame: it owns the scales, draws the axes, and hosts mark layers. fill="amount" colours the bars by a COLOR scale.

<bars><data><plot><record>

Coxcomb

<bars><column><data><plot><record><style>

Darklight

Digital Tolkien "Little Delving #0018" — a DIVERGING bar chart, in the reusable rust-on-cream house frame.

<column><data><define><delving-rust><diverging><record>

Dashboard

Named grid areas: an "app shell". The areas template paints a picture of the layout; each child places itself into a named region with area="...", and a name repeated across cells spans them (header and footer span both columns). columns="150px 1fr" and rows="56 1fr 42" size the tracks; the 1fr column and row fill. The main region hosts a lazy <plot> that reflows to fill it, and the sidebar a nested stretch column of nav buttons.

<bars><box><column><data><grid><plot>

Facet

<facet> splits the data by a field into small multiples — one plot per region — arranged by the RELATIONAL engine (a row of figures). The y-scale is shared across facets so the panels are comparable.

<bars><data><facet><record>

Fillslide

Slice 1 of the layout-models work (docs/layout-models.md): the chart is a LAZY Figure. The column fills the fixed canvas and stretches its children to full width (align="stretch"); the <plot grow> absorbs the leftover height, so the chart reflows to render at 844x444 instead of its 380x240 default. Retires the old space-between hack with a real fill.

<bars><column><data><plot><record><text>

Flipped

A horizontal bar chart is not an option on <bars>. It is flipped times bars, exactly as a pie is polar times bars: the layers do not change, the coordinate frame does. So flipping applies to a line, an area or a scatter just as readily - and to grouped series, as here. The reason to reach for it: long category names. Upright they crowd the axis and tilt; flipped they read straight, in a gutter sized to fit.

<bars><data><plot><record>

Gantt

The same <timeline> as the episode timelines, against a calendar rather than a clock. The axis reads which it has from the data: a value like "2026-01-05" is a date, "12:30" is elapsed time, and the origin, the gridline spacing and the label format all follow from that. Mixing the two in one timeline is refused - an axis is one or the other.

<data><record><timeline>

Here

Project Amaze Beanbag #151 (projectamaze.com/beanbag/151/): relative frequency of the word "here" per book section, coloured for Earth (green) vs Space (purple), with grey background bars for the enclosing chapters (ticked + numbered).

<data><record><spine>

Histogram

Little Delving #0005: a histogram (gapless binned bars) with axis titles and a leader-line annotation to the longest-paragraph outlier.

<column><data><define><delving-blue><histogram><record>

Kpis

An analytics board, and a check that a dashboard is a composition like anything else here: there is no KPI element, no gauge element and no heatmap element. A tile is a <define> used four times. A gauge is a ring told where to start and when to stop (hole, sweep, start-angle), with the number laid over it by a <stack>; the legend is declined because that number is the key. The matrix is <points> on two bands: x has always had one and y takes one when it names a category. The quota bar is a <stack> whose track fills across with justify="stretch" and whose fill is laid over the start of it. The shell is a <grid> of named areas, as examples/dashboard.svgn shows on its own.

<area><bars><contains><data><define><grid>

Line

Layers compose: an <area> under a <line> under <points>. They share the plot's scales, and are drawn in document order.

<area><data><line><plot><points><record>

Logscale

A scale is a component, like the frame and the position. Band or linear can be read off the data; a LOG axis cannot, because nothing in the numbers says you want one. It is a choice about what you are showing, so you name it. What it buys, side by side below: on a linear axis six years of growth are one spike and five points squashed on the floor. On a log axis equal RATIOS take equal space, so steady multiplication reads as a straight line - and you can see the growth rate change. A log axis has no zero and no negatives. There is no point on it for them, so they are refused rather than clamped into a lie.

<data><line><plot><points><record><row>

Phases

<column><data><record><style><text><timeline>

Pie

pie = bars + polar. The SAME bars layer, in polar coordinates, becomes a pie: each value is an angular slice, coloured by an ordinal scale, with a legend. "A graphic is a composition, not a type."

<bars><data><plot><record>

Precious

Little Delving #0014: single-series bars, each coloured by position (fill="index" -> the oklch rainbow), in the reusable blue slide frame.

<bars><column><data><define><delving-blue><plot>

Pronouns

Project Amaze Beanbag #147 (projectamaze.com/beanbag/147/): the percentage of first-person pronouns that are plural, per section of the Space timeline. A minimal bar chart: value labels on top, section labels below, no axes.

<bars><data><plot><record>

Proportional

<bars><column><data><plot><record><row>

Quadrant

A quadrant chart is a scatter plus a crosshair plus names. <rule> draws the two dividers in DATA coordinates, so they stay on the 0.5 lines whatever the plot is sized to, and labels names each point - without which the dots say nothing about which thing they stand for.

<data><plot><points><record><rule>

Radar

A radar is the same idea as a pie, one layer along. Bars in polar read the value as an ANGLE and you get a pie; a line or an area reads it as a RADIUS along one of the spokes and you get a radar. The rows are the spokes, and several y fields are several overlaid shapes. "A graphic is a composition, not a type" - neither of these is a chart kind, they are the coordinate frame times the layer.

<area><data><plot><record>

Regiontimeline

Digital Tolkien "Region Timeline" for The Rings of Power S1E1 (rop.digitaltolkien.com, episode page): lanes = the regions the story visits, blocks = when it is there, coloured per region (and the row label tinted to match). Colours are the site's canonical region palette. sort="time" orders the lanes by first appearance, so reading top-to-bottom follows the episode's journey: Prologue -> Forodwaith -> ... -> End Titles.

<data><record><timeline>

Scatter

A numeric x makes the x-axis a LINEAR scale (not band). <points> is a scatter layer; fill="score" colours each point by a color scale.

<data><plot><points><record>

Smartart

A sheet of the shapes PowerPoint calls SmartArt: a chevron process, a pyramid, a funnel, a Venn, a target and a quadrant matrix. None of them is a diagram type. The chevrons and the pyramid and funnel bands are one <polygon points="...">, which is the whole reason this example exists: sides builds a regular polygon and a chevron is not one, so an arbitrary outline used to be reachable only from Python. The overlaps are a <stack>, the concentric rings are a <stack> of sized circles, and the matrix is a <grid>. A negative gap is what laps one chevron over the next. The picture list is <image>: its href is relative and its bytes are embedded, so this file needs the asset beside it and the compiled SVG needs nothing at all. The badge over the second one is a <stack> putting a mark in a corner of the picture. What is worth copying: a shape you use more than once is a <define>, so the outline is written once and named after what it means.

<band><bars><chevron><circle><column><data>

Speechtimeline

Digital Tolkien "Speech Timeline" for The Rings of Power S1E1 (episode page): lanes = every speaking character, blocks = their lines, coloured by RACE (elves purple, harfoots green, lowmen gold) with the row label tinted to match. small rows (bar-height 30); sort="time" so the cast appears in speaking order.

<data><record><timeline>

Stacked

Stacking is a POSITION ADJUSTMENT - a component of the grammar beside the mark and the frame, not an option belonging to bars. So it is spelled the same on every layer, and it meets every coordinate frame. Which is why the README's line finally describes the language rather than gesturing at it: a pie IS polar x bars x stack, and asking for the other reading in polar names the chart you would get (a coxcomb) instead of being quietly ignored. Grouped answers "how do the teams compare this month?"; stacked answers "how big was the month, and who made it up?"

<area><bars><column><data><plot><record>

Strider

Little Delving #0004 as a full slide, using belladonna's exact specs: 1440x1080 canvas, a space-between column (header top / chart / footer bottom-right via align-self), Merriweather title, oklch bar palette.

<bars><column><data><plot><record><style>

Tense

Project Amaze Beanbag #42 (projectamaze.com/beanbag/42/): present vs past tense per book section, split by Earth/Space and narration/speech. A scatter with a diagonal reference line (present+past=100), axis titles and a legend. Colours are Project Amaze's exact lch values: each timeline a hue (Space purple 295, Earth green 142), narration light and speech dark.

<data><plot><points><record><rule>

Timeline

Digital Tolkien "Episode Timeline" for Durin (rop.digitaltolkien.com/character/durin/): lanes = episodes he speaks in, blocks = his 424 speech lines, one dwarf-red colour.

<data><record><timeline>

Layout 17

8008

Intel 8008, from a Mermaid flowchart LR with one subgraph. What maps to what: subgraph becomes a <contains>, and flowchart LR becomes layout="graph" direction="lr" ON that contains, so the boundary and the layout are one element rather than two. Each Mermaid link becomes one <connect>; a double-headed one becomes <connect arrow="both">, which is a single edge with a head at each end, not two edges. (The Mermaid cannot be quoted here verbatim: its double-headed arrow ends an XML comment.) Nothing here says where any on-chip unit goes. The <contains> that draws the 8008 boundary IS the graph (layout="graph" direction="lr", which also takes Mermaid's own direction codes), and the layered layout works the seven units out from the seven internal edges alone. memory and ports sit outside it and the five crossing edges are drawn without moving anything, since only a graph's own internal edges shape it. Two things the picture depends on. moves="false" on the registers/ALU link. It is a bidirectional bus, not a step in a flow, so it should not push the ALU a layer downstream of the register file. Declaring it a relation rather than a step puts control's three targets on one layer and turns the bus into the short vertical double arrow it really is. The edge still draws, with both heads; it just stops deciding the layering. Without it: two crossings. arrow="both" is Mermaid's double-headed arrow. arrow says which ENDS bear a head; head/tail say which SHAPE it is. So tail="arrow" sets the shape of an end that by default is not drawn. It compiles, and does nothing.

<column><connect><contains><rect><row><style>

Aligncontent

align-content distributes the lines of a wrap along the CROSS axis, the way justify distributes items along the main axis. Here tags wrap into lines by width, and align-content="space-between" spreads those lines to fill the fixed height. It only bites because the row has a definite height with spare room. Same _distribute() helper as justify, applied cross-axis.

<box><row>

Aspect

aspect-ratio: an element derives whichever axis is left auto from the one it's given. The hero fills the stretch column's width and takes a 16:9 height; each thumbnail fills its 1fr grid column and takes a 1:1 (square) height. Same "resolve one axis, derive the other" hook as text wrapping.

<box><column><grid>

Autograph

<graph> is the one combinator that decides for you. Nothing below says where anything goes: the rows, the order within each row, and the straight spine down the middle are all read off the <connect> elements, by the same Sugiyama recipe Graphviz's dot runs. Compare with flowchart, which draws a similar shape by stating it — a <column> of <row>s. Both are legitimate. A shape you know is clearer stated; one that falls out of the edges, or that changes when the edges do, is better computed. Note lint and unit share a row because they share a predecessor, and report sits under both because it depends on both — a diamond nobody laid out.

<connect><diamond><ellipse><graph><rect><style>

Bento

Explicit line-number placement. A child can claim a track range by 1-based grid lines: grid-column="1 / 3" spans columns 1-2; grid-row="1 / 3" spans rows 1-2 (so "Featured" is a 2x2 tile). "Wide banner" spans two columns (grid-column="3 / 5"). Everything else auto-flows into the cells left free. Placement is unified with named areas + auto-flow behind one per-child track range, so track-sizing and painting didn't change.

<box><grid>

Cards

Per-item stretch in a wrap line: align="stretch" makes every card fill its LINE's cross size, so cards in the same row share a height even though their bodies wrap to different lengths (the classic equal-height card grid). It only stretches items that don't pin that axis; a card's width is pinned, so only the height fills. Each row's height is the tallest card in it.

<contains><row><text>

Cellpercent

Percentage sizing inside grid cells. Each bar is a direct grid child sized to a % of its cell: the 1fr value column, shared across rows, so the bars are comparable. A sized grid item keeps its size and sits at the cell's start (left), which is exactly what turns "% of the cell" into a horizontal bar chart. The label column is max-content; the bars fill the row height.

<box><grid><text>

Flowchart Lr

The same <graph> as flowchart.svgn, turned on its side. Only the downward layout is actually computed: flowing rightward is that layout with every node's size transposed and the offsets transposed back, so layer assignment, crossing reduction and straightening stay ONE implementation rather than four that can drift apart. direction takes down/right/up/left, and Mermaid's and Graphviz's codes (td, tb, lr, bt, rl) too, since those are what you will have typed.

<connect><diamond><ellipse><graph><rect>

Gaps

Separate row/column gaps. column-gap tightens the columns while row-gap opens space between the rows (or write both at once as gap="row col"). Here a tight column-gap and a loose row-gap split the tiles into two clear horizontal bands, days over times. gap= alone still sets both axes.

<box><grid>

Jobstate

Another <graph> (see autograph), but this one has a cycle: retry runs from Failed back to Queued. A layered drawing has to flow one way, and a cycle has no one way to flow — so the engine reverses a minimal set of edges to break every cycle, found by a depth-first search, lays the rest out top-down, then draws the reversed ones against the flow. retry climbs the left margin from the bottom back up to Queued, routed around the boxes in its way. poll is a self-loop, Running to itself. It arches off a side the node's other edges leave free — here the right — rather than always the top, where in a downward flow the incoming edges land. Nothing here is placed by hand: the four states, the branch to Failed and Done, the self-loop and the cycle are all read off the five <connect> elements. Rewrite the transitions and the whole picture re-lays itself.

<connect><ellipse><graph><style>

Masthead

Negative grid lines count from the end: line -1 is the last line, so grid-column="1 / -1" spans every column whatever the count. Here the header and footer go full-bleed over a 3-column grid without naming areas; the three tiles auto-flow into the row between them. (Negatives resolve against the track count: columns always know it; row negatives use the rows list.)

<box><grid>

Mindmap

<graph> flows one way, which is right for a process and wrong for a mindmap: a mindmap has a middle and grows outward in every direction at once. <radial> is the same bargain - give it marks and connect them, and it decides where they go - but in rings rather than rows. Each branch takes a wedge in proportion to how many LEAVES it holds, not how many nodes, because leaves are what need room on the rim.

<connect><ellipse><radial><rect><style>

Shapes

<polygon> describes its outline instead of naming it. sides is what a polygon is; skew, distortion and orientation lean, taper and turn it. Every one of these is a PolygonMark like the built-ins, so connectors clip to the outline rather than to the bounding box.

<column><polygon><row><style>

Stack

Shapes carry meaning here without a word: a cylinder is a datastore, a parallelogram is I/O, a diamond is a decision. <cylinder> (aliases <database>, <db>) is the one built-in shape a polygon cannot express - it draws as two paths, the silhouette and the front of its lid, which is what makes it read as a solid rather than a rounded box. A stadium needs no shape of its own: SVG clamps rx to half the height, so <rect rx="99"> already is one - see "Request" below.

<connect><cylinder><db><diamond><graph><io>

Table

Slice 2 of the layout-models work: a real grid. Columns are "max-content repeat(3, 1fr)": a label column as wide as its widest cell, then three equal fractional columns. Cells share tracks, so every column lines up across rows (a column-of-rows couldn't guarantee that). The 1fr tracks fill because the diagram width makes the grid definite.

<grid><rect><text>

Tags

Flex-wrap: a row of pill-shaped chips, each sized to its label, that wrap onto new lines when they'd overflow the definite width. The container's height grows to fit however many lines result (the wrapped cross extent is computed at measure time because the width is known from the canvas).

<rect><row><style>

Toolbar

justify-items / align-items (and per-item justify-self / align-self) align a grid item WITHIN its cell, on each axis independently. Default is stretch (fill the cell); any other value sizes the item to content and positions it. Here three items share a repeat(3, 1fr) row: one start, one centre, one end on the x-axis, all centred on the y-axis by align-items: a classic toolbar (logo left, title centred, actions right) from a single even grid.

<box><grid><text>