Skip to content
TYPO3Soul Design System

Diagrams

A diagram carries an explanation that prose alone shows slower, and the set is the system's visual leitmotif. A shared grammar keeps them from one-off drawings whose colour, geometry and meaning a reader learns again each time.

One claim per diagram. The title states it, the closing line states its consequence. Two claims are two diagrams.

If the drawing still works as a bulleted list, it is not a diagram. Position, length or alignment carries the meaning. Boxes and arrows are the last resort, not the first vocabulary.

Solid means there. A dashed outline of the same shape means absent or not yet reachable, so a shortfall has a size, not a sentence. Where the absent part is a degradation, not a precondition, the dashed outline carries --status-warn.

Orange marks the one thing the diagram is about: exactly one element per drawing, often a connector, since the claim is usually a relation. When the drawing is about degradation or failure, status colour replaces the accent and orange stays out.

The numbers#

Canvas viewBox="0 0 1200 H", always 1200 wide, height to fit. No radius, shadow, gradient or texture
Margin 60 units every side. Nothing enters it, labels included
Type Source Sans 3; identifiers, paths and flags in Source Code Pro. Title 36 · lead 17 · node title 16 · node body 14 · label 13. 13 is the floor
Stroke 1 node outline, 1.5 connector or boundary, 2 for the one accented connector
Radius 6 node or boundary, 4 bar, 2 unit square. Never above 6
Node --surface-raised, 1px --border-subtle, radius 6. Peers share one treatment; their names tell them apart, not their hues
Boundary Hairline only, no fill. A filled container makes depth out of colour
Connector 1.5px, orthogonal, one arrowhead, --text-muted. No curves. Dashed means optional or not yet, and nothing else

Colour is an attribute, never a <style> block, which GitHub strips. Each attribute is the token with the light hex behind it, fill="var(--text-primary, #1C1A17)". The hex is what a page shows, and the token is ready for the day a page can read it. Ship that one file and wrap its shapes in <g id="soul-ref">, the handle make diagrams reads them out from under for the specimen cards. Artwork holds the whole file contract.

A diagram sits on --surface-sunken. The drawing brings its own canvas, which makes it read as a figure with clear space. On --surface-canvas it dissolves into the page.

On a slide#

A drawing for a slide keeps the grammar and leaves the frame. It has no eyebrow, no title and no closing line: the slide's head says them. It has no margin, as the slide's margin is its margin. Its canvas is the room of its layout in the frame's pixels, which Slides states, and not 1200 wide. A drawing in parts is a row of drawings: the slide gives each its plane, its word and its caption as text. slide-lookup.svg is one drawing for wide, the three slide-cache-*.svg a row.

Drawing rules#

Drawing rules · 980x650

Worked examples#

Different shapes of claim need different structures. The examples below use an axis, a sequence and containment instead of boxes joined by arrows.

System overview — a map with no axis · 1400x966
Worked example · 1400x1014
Fallback — a sequence without a flowchart · 1400x1034

Another one#

The rules above as an instruction for a drawing tool, with the file contract and the negative constraints. It stands here in full because it is a thing to hand over. Copy the whole block and replace [CLAIM] and [CONSEQUENCE], the only two fields that change. New numbers or new states start a second grammar, and a set in two grammars costs a reader at every drawing.

A diagram is the one drawing that does not come back as a picture. The result is the SVG itself, because its colours are tokens and `make diagrams` reads its shapes out for the cards above.

The diagram prompt — replace only the claim and its consequence
markdown
# Explanatory diagrams

A diagram carries a claim. An illustration only sets a register beside the
heading it stands under. If a reader need not understand a position, a
connection or a quantity in the image, draw an illustration instead:
`docs/design-system/illustration-prompt.md` is that prompt.

A diagram does not come back as a picture. It is one SVG file in the grammar
below, shipped as source. The colours in it are tokens a page can reach into,
and `make diagrams` reads the shapes back out for the specimen cards.

## The fixed language

- **Canvas:** `viewBox="0 0 1200 H"`, always 1200 wide, the height to fit. A
  flat rectangle at `var(--surface-canvas, #FBFAF7)` fills it. No radius,
  shadow, gradient or texture.
- **Margin:** 60 units every side. Nothing enters it, labels included.
- **Type:** Source Sans 3, with identifiers, paths and flags in Source Code
  Pro. Title 36 · lead 17 · node title 16 · node body 14 · label 13. **13 is
  the floor.** A diagram that needs smaller type carries too much.
- **Stroke:** 1 node outline, 1.5 connector or boundary, 2 for the one
  accented connector.
- **Radius:** 6 node or boundary, 4 bar, 2 unit square. Never above 6.
- **The two states:** solid means there. A dashed outline of the same shape
  in the same place means absent or not yet reachable. So a shortfall has a
  *size*, not a sentence. Dashed means nothing else.
- **Colour:** names tell peers apart, never hue. Exactly one element carries
  the accent, often a connector, since the claim is usually a relation.
- **Accessibility:** the drawing is the explanation, never decoration. The
  root names a `<title>` with the claim and a `<desc>` with the axes.

## Prompt

Replace `[CLAIM]` and `[CONSEQUENCE]` and leave the rest unchanged:

```text
Use case: explanatory diagram
Asset type: one hand-written SVG file, 1200 units wide, height to fit

Primary request: Draw a diagram that makes this single claim visible:
[CLAIM]. The line it closes on is: [CONSEQUENCE].

Canvas: viewBox="0 0 1200 H", H chosen to fit the drawing. A flat rectangle at
var(--surface-canvas, #FBFAF7) fills it. 60 units of margin on every side, and
nothing enters that margin, labels included. No outer radius, no shadow, no
gradient, no texture anywhere in the file.

Structure: the claim is carried by position, length or alignment — an axis, a
sequence, containment, a span across a scale. Boxes joined by arrows are the
last resort, not the starting vocabulary. If the drawing would still work as a
bulleted list, change the structure rather than adding detail to it.

Frame: an eyebrow in Source Code Pro at 13, uppercase and letter-spaced, in
var(--accent, #FF8700); the title under it at 36 bold in
var(--text-primary, #1C1A17); one lead line at 17 in
var(--text-secondary, #4A453D); a 1-unit rule in
var(--border-subtle, #E3DFD6) across the full width. At the foot, a 1-unit
rule in var(--border-strong, #C9C3B7), the consequence at 16 semibold, and one
line under it at 14.

Type: 'Source Sans 3' with a system-ui fallback for prose, 'Source Code Pro'
with a monospace fallback for identifiers, paths and flags. Node title 16
semibold, node body 14, label 13. 13 is the floor and nothing goes under it.

Shapes: node radius 6, bar radius 4, unit square radius 2, never above 6. A
node is var(--surface-raised, #FFFFFF) behind a 1-unit
var(--border-subtle, #E3DFD6) outline. A boundary is a hairline with no fill —
a filled container makes depth out of colour. A connector is 1.5 units,
orthogonal, one arrowhead, var(--text-muted, #726C63), and never curved.

The two states: a filled shape is what you get. A dashed outline of that same
shape, in that same place, is what is missing or not yet reachable, drawn in
var(--text-muted, #726C63). Dashed carries no other meaning. Where the missing
part is a degradation rather than a precondition, the dashed outline takes
var(--status-warn, #986200) instead.

Colour: peers share one treatment and are distinguished by their names, never
by hue. Ink is var(--text-primary, #1C1A17), a quieter line
var(--text-secondary, #4A453D), a label var(--text-muted, #726C63). Exactly
one element in the whole drawing carries var(--accent, #FF8700), and it is the
one thing the diagram is about. Where the diagram is about degradation or
failure, status colour replaces the accent and orange stays out entirely.

File contract: every colour is a presentation attribute written as a var()
with the light hex behind it. No style block, and no fill or color on the root
element. The root carries role="img" and aria-labelledby pointing at a title
and a desc inside it. Every drawn shape sits inside one group with the id
soul-ref. No comment in the file may contain two dashes in a row: that is
malformed XML, and such a file draws nothing wherever it is fetched.

Constraints: one claim and no second one; no legend repeating what the shapes
already say, no colour key, no hue palette, no icon set, no screenshot of an
interface, no logo, no watermark.

Avoid: flowcharts of everything, decorative or double-headed arrows, curved
connectors, drop shadows, elevation, rounded canvases, multicoloured node
sets, isometric or three-dimensional treatment, clip art, dense small type,
fine hatching and decorative clutter.
```

## The claim

Write the claim as a sentence before you draw. A topic, "how the sources
work", has nothing to draw. A claim, "bundled knowledge is the only source
that spans the whole axis", decides the structure by itself. It names the
thing under comparison and the scale of the comparison.

The title states the claim and the closing line states its consequence. Two
claims are two diagrams. A drawing that carries both ends up as boxes joined
by arrows, the shape of a claim that has stopped being one.

Then pick the structure from the claim, not from the shapes. A span along a
scale wants an axis. A thing that must happen before another wants a
sequence. A thing that holds others wants containment. Boxes and arrows are
what remains when none of those fits.

Which drawings a set holds is a property of that set, not of this prompt.
`packages/frontend/assets/diagrams/` owns that list. A copy here is an
inventory that falls behind the files.

## What to hand back

One file in `packages/frontend/assets/diagrams/`, named after the claim, not
the drawing. Then `make diagrams`. It reads the shapes out from under
`soul-ref` for the specimen cards. It refuses a file without the group or
the `viewBox`, and a file with a comment that is not valid XML.

Look at it twice. At 1200 wide, where a reader reads the type. And at the
width a card gives it, where only position, length and alignment survive. If
the second view no longer makes the claim, the claim was in the labels.