Visuals — Images, Icons & Diagrams
A diagram or a well-placed icon does what a paragraph can't. This page covers raster/vector images, icons, and live Mermaid diagrams.
Images
Drop files in public/ and reference them with an unprefixed path (no locale). Plain
Markdown works, and images get click-to-zoom by default.

For finer control use :img (set width/height, or disable zoom):
:img{src="/images/klstr-one.png" alt="KLSTR.one front panel" width="480" zoom="false"}
:color-mode-image{light="/diagram-light.svg" dark="/diagram-dark.svg" alt="…"} swaps automatically with the light/dark toggle. SVG illustrations in public/ stay crisp at any size and theme.File downloads
To offer a file (firmware image, PDF, archive), drop it in public/ and link it with a
button carrying external and download:
:u-button{label="Download sniffer.klstr.nano" icon="i-lucide-download" to="/firmware/sniffer.klstr.nano" external download="sniffer.klstr.nano"}
download the filename, never write it bare. MDC turns a valueless prop into
the string "true", and the download attribute's value is the suggested filename, so
a bare download saves the file as true with no extension. Always write
download="the-real-filename.ext".::note / ::tip / ::warning style every
descendant link with arbitrary variants like [&_a]:text-success. Those compile to a
descendant selector, which outranks the button's own text-inverted, so the label takes
the callout's colour and becomes unreadable against the button fill. Put buttons in the
page body and use plain prose for the surrounding note.external is not optional, and its absence is the whole trap. i18n rewrites every
internal link to include the current locale, so to="/firmware/x.bin" renders as
href="/en/firmware/x.bin" and 404s. This happens to a plain Markdown link
([text](/firmware/x.bin)) and to a raw <a href> too, because MDC routes both through
the same link component. external makes it render a plain anchor and the path survives
untouched. download then saves the file instead of navigating to it.Images are exempt: they go through the image pipeline (/_ipx/…), which is why
 needs no special treatment.public/ is not tiered. Every build ships the whole folder, so a file placed there
is reachable by URL on the public site as well, even when the page linking to it is
cloud or internal only. It is unlisted, not protected. Anything that must be restricted
needs a real gate, not a public/ path.Icons
Any Iconify icon works via :icon{name="…"}. This site uses the
Lucide set by default (i-lucide-*); other collections work with their prefix
(i-simple-icons-gitlab, i-logos-cloudflare, …).
:icon{name="i-lucide-cpu"} :icon{name="i-lucide-network"} :icon{name="i-lucide-shield-check"} :icon{name="i-simple-icons-cloudflare"}
The same i-lucide-* names are what you put in .navigation.yml icon: and on ::card /
::callout icon props.
Mermaid diagrams
::mermaid renders diagrams from text — flowcharts, sequences, state machines, ER, Gantt
and more. It follows the site's light/dark mode. Pass the definition as a YAML code: |
block so Markdown leaves the arrows alone.
Flowchart
Loading diagram…
::mermaid
---
code: |
graph TD
A[Browser request] -->|JWT cookie| B(Worker middleware)
B --> C{app_role}
C -->|admin| D[Render internal docs]
C -->|other| E[302 → /login]
---
::
Sequence diagram
Loading diagram…
Architecture / graph
Loading diagram…