flows.md · documentação
Referência#
Toda cerca que uma página pode chamar, com seus argumentos, seu corpo e um exemplo. Nada aqui é escrito à mão: a lista abaixo é uma cerca — @components — e sai da declaração dos próprios componentes. Uma referência com a lista de argumentos copiada é uma página que envelhece na semana seguinte.
Page components
A fenced code block whose language starts with @ is a call to a component. Everything below is generated from the components themselves, so it cannot go stale.
@audio
renders: server
An audio player over a file uploaded to this site. Controls on, nothing autoplays.
Server rendered.
Example
```@audio src:/rails/active_storage/blobs/redirect/abc/episodio.mp3 title:"Episódio 1"
```
Arguments
-
srcpath Required - Path of the file on this site, usually an upload of the page. Starts with a single / — "//host/x" is another site, not a path.
-
titlestring - A short title shown under the player.
-
preloadenum Default: metadata - How much the browser fetches before play: none, metadata or auto. Allowed: none, metadata, auto
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@components
renders: server
The reference for every fence a page may call, generated from the components' own declarations.
Server rendered.
Example
```@components
```
Arguments
-
onlyenum Default: all - Which half to list: `server`, `client`, or `all` (the default). Allowed: all, server, client
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@consent
renders: server
The reader's yes or no, one line per purpose (flags | label | description | required), remembered on this site as flags the reader owns. One purpose is two buttons; several are switches with accept all, reject all and save. Put it inside a :::banner for a cookie notice.
Server rendered.
Example
```@consent title:"Sua privacidade" link:/privacidade
essential | Essenciais | Mantêm o site funcionando. | required
videos | Vídeos do YouTube | Carrega o player do Google, que usa cookies.
```
Arguments
-
titlestring - A heading above the purposes.
-
linkstring - Where the full policy is: a page of this site (/privacidade) or a web address starting with https://.
-
acceptstring - The words on the button that says yes to everything. Default: Accept all.
-
rejectstring - The words on the button that says no to everything but the required. Default: Reject all.
-
savestring - The words on the button that keeps the switches as they are. Default: Save choices.
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
One instruction per line. One purpose per line: the flags it sets (space-separated), a `|`, the label, a `|`, what it means; `| required` at the end for one that is always on.
@contact
renders: server
A person or a place to reach: call, WhatsApp with a written message, e-mail, map — and a button that saves the contact to the phone.
Server rendered.
Example
```@contact name:"Vitória Imóveis" role:"Corretora" whatsapp:"+55 11 95550-0134" message:"Olá! Vi sua página." email:[email protected]
```
Arguments
-
namestring Required - Who this is.
-
rolestring - What they do, under the name.
-
orgstring - The company or the place.
-
phonestring - A telephone number, with the country code: "+55 11 5550-0134".
-
whatsappstring - The WhatsApp number, with the country code. It opens a conversation.
-
messagestring - What the WhatsApp conversation starts with, already written for the person.
-
emailstring - An e-mail address.
-
sitestring - A web address, starting with https://.
-
addressstring - Where it is. It opens the map.
-
saveboolean Default: true - Whether the "Save contact" button is shown.
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@copy
renders: server
A value to take away — a Pix key, a coupon, a wifi password, a command — printed, with a button that copies it.
Server rendered.
Example
```@copy label:"Chave Pix" value:[email protected] note:"Any amount helps"
```
Arguments
-
valuestring - What is copied. Write it here when it is short, or in the body when it is long or has spaces and quotes.
-
labelstring - What the value is, printed above it.
-
notestring - One line under the value: until when it is valid, where to paste it.
-
kindenum Default: text - text for a key or a code a person reads; code for something pasted into a terminal, kept on its own lines. Allowed: text, code
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
Free text. The value, when it does not fit on the fence line. The body wins over `value`.
@countdown
renders: server
Counts down to a date and time, and says something else once it has come. A launch, a drop, doors opening, enrolment closing.
Server rendered.
Example
```@countdown to:2026-11-20T19:00-03:00 label:"Doors open" done:"We are open"
```
Arguments
-
tostring Required - The moment, as 2026-11-20 or 2026-11-20T19:00-03:00. With no offset it is read as UTC; a date alone is its first minute.
-
labelstring - What is being waited for, printed above the clock.
-
donestring - What the block says once the moment has passed. Without it the block says the moment has come.
-
showenum Default: full - full counts days, hours, minutes and seconds; days counts only days, for something weeks away. Allowed: full, days
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@data
renders: server
Reads a collection of this space and renders it as a table, with filters, columns, metrics and pagination.
Server rendered.
Example
```@data collection:inscricoes sort:-created_at limit:10
@filter status eq aberto
@count
@column nome label:"Quem"
@column status format:badge
```
Arguments
-
collectionstring Required - The name of the collection inside this space, without the @space prefix.
-
limitinteger Default: 25 - How many rows per page (1–100). Defaults to 25. Allowed: 1 to 100
-
offsetinteger Default: 0 - How many rows to skip before the first page. Allowed: 0 to 100000
-
sortstring - A field to sort by; a leading minus reverses it (`-created_at`).
-
includelist - Reference fields to resolve, comma separated. Shown references are resolved anyway.
-
fieldslist - Which fields to show, comma separated. Defaults to every stored field plus created_at.
-
scopeenum - viewer: each person sees only the rows they created. Allowed: viewer
-
emptystring - What to say when there is no row to show.
-
exportboolean Default: false - Adds CSV and JSON links for the whole filtered collection — the fence's filters, sort, scope and columns, but not its limit or offset.
-
page_paramstring Default: page - The query parameter this table pages on. Give two tables different ones.
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
One instruction per line. Optional children: `@filter field op value`, `@column field label:"…" format:…` (one field of this collection; a reference like `@column prova` prints the row it points at, and there are no dotted paths; `format:image` on a url field shows the picture as a thumbnail kept on this site, and a click opens it), and the metrics `@count`, `@sum field`, `@avg field`, `@min field`, `@max field`.
Accepted children
@filter, @column, @count, @sum, @avg, @min, @max
@flashcards
renders: server
A deck of cards to drill: a term and its meaning, a question and its answer, a word and its translation. One card per line, front | back. Turned by a click or the keyboard; printed in full without a script.
Server rendered.
Example
```@flashcards label:"DNS do envio"
SPF | Diz quais servidores podem enviar em nome do domínio.
DKIM | Assina cada mensagem; o destinatário confere no DNS.
```
Arguments
-
labelstring - A line above the deck saying what it drills.
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
One instruction per line. One card per line: the front, a `|`, the back.
@form
renders: server
A form that writes a row into a collection of this space. Only renders for somebody the collection accepts.
Server rendered.
Example
```@form collection:inscricoes submit:"Quero entrar"
nome
email required
```
```@form collection:lista layout:inline submit:"Assinar"
email required
```
```@form collection:inscricoes mode:edit own:true
nome
email required
```
Arguments
-
collectionstring Required - The name of the collection inside this space, without the @space prefix.
-
successstring - What to say after a row goes in. Defaults to a thank-you.
-
submitstring - The label of the button. Defaults to "Send".
-
scopeenum - viewer: require sign-in and attribute the row to the sender. Use scope:viewer on reads to show only that person's rows; collection visibility still controls other reads. Allowed: viewer
-
modeenum Default: create - create: a form that adds a row. edit: a form that changes one of the viewer's own rows; it needs own:true. Allowed: create, edit
-
layoutenum Default: stacked - stacked: one field under the other, each with its label. inline: the fields and the button in one row — for a signup of one or two fields; the labels become the hints inside the fields and stay readable to a screen reader. Allowed: stacked, inline
-
ownboolean Default: false - true: list the rows this viewer created, each with a link that opens it in the form. Signed-in people only.
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
One instruction per line. One field per line, a subset of the collection's schema: `email required`, `nome`, `mensagem long_text`. Options must match the collection schema; change @schema first to override them. Empty body: every writable field, in schema order.
@hours
renders: server
When a place is open: the week, printed, and "open now" by the clock of the place. For a venue, a shop, a clinic, a contact page.
Server rendered.
Example
```@hours zone:America/Sao_Paulo notice:"Closed on the 12th"
mon-fri 11:30-15:00, 18:00-23:00
sat 12:00-00:00
sun closed
```
Arguments
-
zonestring Required - The time zone of the place, as the tz database names it: America/Sao_Paulo, Europe/Lisbon. "Open now" is read on that clock, not the reader's.
-
titlestring - A heading over the week.
-
noticestring - One line under the week: a holiday, new hours, "kitchen closes 30 minutes earlier".
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
One instruction per line. One line per day or run of days, then the hours: `mon-fri 09:00-18:00`, `sat 10:00-14:00, 16:00-20:00`, `sun closed`. Days in English or Portuguese. An end before the start runs past midnight.
@members
renders: server
The people in a group: name, a line about them, who runs it. Shown only to those the group lets see its list (its managers; its members when the group says so). Nothing for anybody else.
Server rendered.
Example
```@members group:"Turma 3" label:"Quem está na turma"
```
Arguments
-
groupstring Required - The group, by name or id. A name must be one you stand in, or a group with a door (by_request, open).
-
labelstring - A line above the list.
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@pages
renders: server
Also written ```pages
A gallery of the pages listed in the body, each one a picture of itself. Only pages the reader may open are shown.
Server rendered.
Example
```@pages columns:2
/@docs/showcase/dashboard
/@docs/showcase/link-pages | /@docs/showcase/link-pages/nara
```
Arguments
-
columnsinteger Default: 3 - How many cards per row (1–4). Defaults to 3. Allowed: 1 to 4
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
One instruction per line. One page path per line. `/a/section | /a/section/one` links to the first and pictures the second.
@patterns
renders: server
The section pattern library: every pattern, grouped, with a link to it rendered and its markdown to copy.
Server rendered.
Example
```@patterns
```
Arguments
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@qr
renders: server
A QR code of this page, or of another address: for a table, a slide, a poster, a card. Dark on white whatever the theme, so a camera reads it.
Server rendered.
Example
Arguments
-
tostring - What the code opens: a path of this site (/@ana/menu) or a web address starting with https://. Without it, the page the block is on.
-
labelstring - A line under the code, saying what it opens.
-
sizeenum Default: medium - How large it is drawn on the screen. It prints sharp at any size. Allowed: small, medium, large
-
colorstring - The colour of the code itself, as #rrggbb. Dark enough to read against the background, or the block says so.
-
backgroundstring - The colour behind the code, as #rrggbb. White by default, which is what a camera likes best.
-
eyestring - The colour of the three corner squares, as #rrggbb. The colour of the code by default.
-
shapeenum Default: square - The shape of the small modules: square, dots or rounded. The corner squares stay square whatever this says. Allowed: square, dots, rounded
-
logostring - A mark in the middle: `brand` (the mark of this site), `none`, or the path of an image on this site (/demo/mark.png).
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@schema
renders: server
Declares the fields of a collection of this space. It shows the declaration; only somebody with settings on the space can apply it.
Server rendered.
Example
```@schema collection:inscricoes accepts:anyone
nome text required
email email required label:"E-mail"
prova reference:provas
```
Arguments
-
collectionstring Required - The name of the collection inside this space, without the @space prefix.
-
visibilityenum Default: private - Who may READ the rows: private (the space's people) or public (anyone). Private by default. Allowed: private, public
-
acceptsenum Default: nobody - Who may send a row through an @form: nobody, members (signed in) or anyone. Nobody by default. Allowed: nobody, members, anyone
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
One instruction per line. One field per line: `name type [required] [indexed] [label:"…"]`. A type may carry its argument: `select:a,b`, `reference:outra`, `computed:sum(outra.valor)`. Indexed date/datetime fields do not accelerate temporal comparisons.
@themes
renders: server
The starting themes: every whole look an author can begin from, drawn in its own colours, with its theme fence to copy.
Server rendered.
Example
```@themes
```
Arguments
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@video
renders: server
A video player over a file uploaded to this site. Controls on, nothing autoplays.
Server rendered.
Example
```@video src:/rails/active_storage/blobs/redirect/abc/demo.mp4 title:"Como aplicar o esquema"
```
Arguments
-
srcpath Required - Path of the file on this site, usually an upload of the page. Starts with a single / — "//host/x" is another site, not a path.
-
titlestring - A short title shown under the player.
-
preloadenum Default: metadata - How much the browser fetches before play: none, metadata or auto. Allowed: none, metadata, auto
-
posterpath - Path of an image shown before play. Starts with a single / — "//host/x" is another site, not a path.
-
modeenum Default: player - player shows controls and never autoplays; background plays muted, looped and without controls, for the ground of a :::hero (paused when the reader asks for reduced motion). Allowed: player, background
-
consentstring - A flag the reader must have allowed before this block shows (`consent:videos`; several, separated by spaces). It has to be one a `@consent` on this site offers.
Body
This component takes no body.
@chart
renders: client
Also written ```chart
A chart or a table, drawn from CSV: bars, stacked bars, a line, an area, a pie, a donut. A reader can point at a value and hide a series.
Rendered in the browser.
Example
```@chart type:line
title: Pages published
---
month,pages
Jan,3
Feb,7
```
Arguments
-
typeenum Default: bar - Which drawing. `stacked` piles the series of a bar chart; `pie` and `donut` read the first series, one slice per row. Allowed: bar, stacked, line, area, pie, donut, table
-
titletitulostring - Printed above the chart.
Body
CSV, or the whole block as JSON. CSV: the first row names the columns, the first column labels the category axis. The whole body may be JSON instead.
@chat
renders: client
Also written ```chat
A conversation: one message per line, `who: text` with an optional ` @ time`. `me` (or `eu`) sits on the right.
Rendered in the browser.
Example
```@chat title:Suporte
ana: Oi, chegou?
me: Chegou sim @ 10:42
```
Arguments
-
titletitulostring - The line above the thread.
Body
One message per line. One `who: text @ time` per line.
@checklist
renders: client
Also written ```checklist
A working checklist: it counts, it groups under ## headings, and it remembers — in the reader's own browser, never on the page.
Rendered in the browser.
Example
```@checklist title:"Antes do deploy"
## Testes
- [ ] Rodar a suite
- [x] Console limpo
```
Arguments
-
titletitulostring - The line above the list.
Body
Items, separated by a --- line. One `- [ ] something` per line, with optional `## Section` headings.
@profile
renders: client
Also written ```profile
The head of a link page: avatar, name, bio and a row of social icons.
Rendered in the browser.
Example
```@profile
name: Nara
bio: A taste of everything
avatar: /demo/nara.svg
instagram: https://instagram.com
```
Arguments
-
namestring Required - The name printed under the avatar.
-
biostring - One paragraph under the name.
-
avatarstring - An image URL, absolute or root-relative.
-
shapeenum Default: circle - The avatar's shape. Allowed: circle, rounded
Body
One link per line. More `platform: url` lines.
@links
renders: client
Also written ```links
Full-width buttons, one per line. A `* ` prefix makes the featured one.
Rendered in the browser.
Example
```@links style:outline
* [Join](https://x.com/join)
[Streams](/streams) every Friday, 8pm
[Live taping](https://x.com/live) July 16 until:2030-07-16
[The mic I use](https://x.com/mic){sponsored}
```
Arguments
-
styleenum - Overrides the theme's button style for this block. Allowed: filled, outline, soft
-
shapeenum - Overrides the theme's button shape for this block. Allowed: square, rounded, pill
Body
One link per line. One `[Label](url)` per line; `` on the line adds a thumbnail; a bare text line is a section heading. Text after the link is a note under the label (`preferred · 20 min`). `from:2026-07-01` and `until:2026-07-16` after the link keep the button on the page only in that window, both days included: a dated link leaves by itself. `{sponsored}` right after the link, as in prose, marks a paid or affiliate button: a visible word and `rel="sponsored nofollow"`.
@reviews
renders: client
Also written ```reviews
A row of review cards, each with its stars.
Rendered in the browser.
Example
```@reviews title:"O que dizem"
★★★★★ Ana
Best bagels in town.
```
Arguments
-
titletitulostring - The line above the row.
Body
Items, separated by a --- line. One review per block, separated by a --- line: `★★★★☆ Name` or `4/5 Name`, then the text.
@faq
renders: client
Also written ```faq
Questions that open, one <details> each.
Rendered in the browser.
Example
```@faq
Do you ship?
Yes, worldwide.
---
Returns?
Within 30 days.
```
Arguments
-
titletitulostring - The line above the questions.
Body
Items, separated by a --- line. One question per block, separated by a --- line: the question line, then the answer.
@embed
renders: client
Also written ```embed
A card that names a provider and links out. Never a frame: the page does not load a third party inside itself (ADR 013).
Rendered in the browser.
Example
Arguments
-
youtubestring - A YouTube URL.
-
spotifystring - A Spotify URL.
-
podcaststring - A podcast URL.
-
videostring - A video URL.
-
calendaragendastring - Where somebody books a time with you: a Cal.com, Calendly or Google Calendar appointment URL.
-
musicmusicastring - A track, an album or a playlist, wherever it lives.
-
applemusicstring - An Apple Music URL.
-
soundcloudstring - A SoundCloud URL.
-
bandcampstring - A Bandcamp URL.
-
deezerstring - A Deezer URL.
-
tiktokstring - A TikTok video or profile URL.
-
instagramstring - An Instagram post or profile URL.
-
twitchstring - A Twitch channel URL.
-
vimeostring - A Vimeo URL.
-
mapstring - An address or a Google Maps URL.
-
mapsstring - The same as map.
-
titletitulostring - The card's first line.
-
notestring - The card's second line.
Body
This component takes no body. This block takes no body.
mermaid
renders: client
A diagram, drawn by mermaid. The one block with no @ spelling: a mermaid fence renders on GitHub, Obsidian, Notion and GitLab, and prefixing it would break the diagram everywhere the export is read.
Rendered in the browser.
Example
Arguments
This component takes no arguments.
Body
A diagram, in mermaid's own grammar. Mermaid source, in mermaid's own grammar.
Layout directives
Lines of ::: arrange the page — bands, columns, grids, media — around ordinary markdown. Every argument is a choice from a list, never CSS, and every layout works from a phone to an ultra-wide screen, in light and dark.
:::section
A band of the page: its width, its surface and the space around it. Everything inside flows top to bottom.
-
widthDefault: normal - normal keeps the reading width, wide uses the page width, full runs edge to edge. Allowed: normal, wide, full
-
surfaceDefault: default - The band's background, from the theme: soft (its surface colour), tint (a wash of its accent), accent (the accent itself), inverse (the theme turned over). Text colours are chosen for contrast, in light and dark schemes. Allowed: default, soft, tint, accent, inverse
-
spaceDefault: 3 - Space above and below, a step of the theme's scale. Allowed: 0, 1, 2, 3, 4, 5
-
alignDefault: left - Where text sits. narrow-center keeps it left on wide screens and centres it on a phone, where a stacked page reads better centred. Allowed: left, center, narrow-center
-
flowDefault: auto - The space between one thing and the next inside it, a step of the theme's scale: one space for everything, whatever the things are. auto keeps each element's own margins, which is what prose wants — a heading further from the paragraph above it than from the one below. Allowed: auto, 0, 1, 2, 3, 4, 5
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::section width:wide surface:soft space:4 align:center
# Automate your routine
Everything between the lines is ordinary markdown.
:::
:::hero
The opening of a page: at least a given height, content centred — with its first or last thing pinned to the top or bottom edge if asked — optionally over a background image with a shade that keeps text readable.
-
heightDefault: half - auto fits the content, half is half the window, screen fills it. Allowed: auto, half, screen
-
mediaDefault: none - background puts the first image inside the hero behind the text. Allowed: none, background
-
shadeDefault: dark - Over a background image: dark (light text) or light (dark text), strong enough for 4.5:1 on any photo. Allowed: dark, light
-
alignDefault: center - Where the content sits. narrow-center is left on wide screens and centred on a phone. Allowed: center, left, narrow-center
-
widthDefault: wide - How wide the content may get. Allowed: normal, wide, full
-
surfaceDefault: default - The ground when there is no background image. Allowed: default, soft, tint, accent, inverse
-
pinDefault: none - Keeps the hero's first thing at its top edge (a logo, an eyebrow), its last at the bottom (a row of logos, a hint to scroll), or both, while the rest stays centred. It shows when the hero is taller than its content: height half or screen. Allowed: none, first, last, both
-
flowDefault: auto - The space between one thing and the next inside it, a step of the theme's scale: one space for everything, whatever the things are. auto keeps each element's own margins, which is what prose wants — a heading further from the paragraph above it than from the one below. Allowed: auto, 0, 1, 2, 3, 4, 5
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::hero height:screen media:background shade:dark

# Work that runs itself
Automate the routine between your tools.
:::
:::split
Two parts side by side — text and media — that stack when there is not room for both. By ratio, the two share the width; with a rail, the first is a side column of a fixed width and the other takes the rest.
Its items are separated by a --- line.
-
ratioDefault: 1/2 - How much of the width the first part takes. Allowed: 1/3, 1/2, 2/3
-
sideDefault: left - Which part comes first on wide screens; on narrow ones the first item is always on top. Allowed: left, right
-
alignDefault: center - Vertical alignment of the two parts. Allowed: start, center, end
-
spaceDefault: 3 - The gap, a step of the theme's scale. Allowed: 1, 2, 3, 4, 5
-
narrowDefault: stack - stack puts the parts one above the other when narrow; keep keeps them side by side. Allowed: stack, keep
-
reverseDefault: none - narrow puts the second part on top when the parts stack, so a picture written after its text comes first on a phone. Allowed: none, narrow
-
stickyDefault: none - Which part stays in place while the other scrolls past it, as a portfolio's side column does. It only sticks while the parts are side by side, never when they stack. Allowed: none, first, second
-
railDefault: none - Makes the first part a side column of that width, in rem, and gives the other part everything else — a side menu, a portfolio's rail, a form beside a text. The side keeps its width on any screen instead of growing with it, and the parts stack when the other would get less than half. With a rail, ratio is not used. Allowed: none, 12, 16, 20, 24
-
flowDefault: auto - The space between one thing and the next inside it, a step of the theme's scale: one space for everything, whatever the things are. auto keeps each element's own margins, which is what prose wants — a heading further from the paragraph above it than from the one below. Allowed: auto, 0, 1, 2, 3, 4, 5
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::split ratio:1/2 side:right
## Text first
A paragraph that sits beside the picture.
---

:::
:::columns
Items side by side in equal columns, all stacking at once when the row gets too narrow.
Its items are separated by a --- line.
-
thresholdDefault: 40 - Below this width, in rem, the columns stack. Allowed: 30, 40, 50, 60
-
limitDefault: 4 - With more items than this, they stack whatever the width. Allowed: 2, 3, 4, 5
-
alignDefault: stretch - Vertical alignment of the columns. Allowed: start, center, end, stretch
-
itemsDefault: plain - card draws each item as a card; stat sets each item's heading as a large number (it counts up when motion is on); step numbers the items as a process. Allowed: plain, card, stat, step
-
spaceDefault: 3 - The gap, a step of the theme's scale. Allowed: 1, 2, 3, 4, 5
-
flowDefault: auto - The space between one thing and the next inside it, a step of the theme's scale: one space for everything, whatever the things are. auto keeps each element's own margins, which is what prose wants — a heading further from the paragraph above it than from the one below. Allowed: auto, 0, 1, 2, 3, 4, 5
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::columns items:card
### Plan
Tell us what you need.
---
### Build
We build it with you.
---
### Launch
It goes live.
:::
:::grid
As many items per row as fit, each at least `min` wide; one per row on a phone. An item can span more columns or rows with :::cell.
Its items are separated by a --- line.
-
minDefault: 16 - The smallest an item may get, in rem, before the row wraps. Allowed: 8, 10, 12, 14, 16, 18, 20, 24, 28
-
colsDefault: auto - At most this many items per row, however wide the page gets. Six items with cols:3 come out as two rows of three instead of five and one alone. A phone still gets one per row. Allowed: auto, 2, 3, 4
-
itemsDefault: plain - card draws each item as a card; stat sets each item's heading as a large number (it counts up when motion is on); step numbers the items as a process. Allowed: plain, card, stat, step
-
alignDefault: stretch - Vertical alignment of items in a row. Allowed: stretch, start, center
-
spaceDefault: 3 - The gap, a step of the theme's scale. Allowed: 1, 2, 3, 4, 5
-
flowDefault: auto - The space between one thing and the next inside it, a step of the theme's scale: one space for everything, whatever the things are. auto keeps each element's own margins, which is what prose wants — a heading further from the paragraph above it than from the one below. Allowed: auto, 0, 1, 2, 3, 4, 5
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::grid min:16 items:card
### Fast
Pages render in milliseconds.
---
### Typed
Nothing you write becomes CSS.
:::
:::cell
Inside a grid item: how many columns and rows that item takes (bento layouts), and which layer it sits on.
-
spanDefault: 1 - Columns the item takes; full takes the whole row. On a phone every item is one column. Allowed: 1, 2, 3, 4, full
-
rowsDefault: 1 - Rows the item takes. Allowed: 1, 2, 3
-
layerDefault: 0 - Stacking order when items overlap (with offset). Allowed: 0, 1, 2, 3
-
flowDefault: auto - The space between one thing and the next inside it, a step of the theme's scale: one space for everything, whatever the things are. auto keeps each element's own margins, which is what prose wants — a heading further from the paragraph above it than from the one below. Allowed: auto, 0, 1, 2, 3, 4, 5
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::grid min:14
:::cell span:2 rows:2

:::
---
### Small tile
:::
:::card
A panel: a surface, padding, the theme's radius, an optional border and shadow.
-
toneDefault: soft - The panel's surface, with contrast-checked text (see section surface). Allowed: default, soft, tint, accent, inverse
-
borderDefault: none - A hairline border. Allowed: none, line
-
shadowDefault: none - A shadow under the panel. Allowed: none, soft, lifted
-
spaceDefault: 2 - Padding inside, a step of the theme's scale. Allowed: 1, 2, 3, 4
-
offsetDefault: 0 - Pull the element up into the content above it, in steps of the scale. Allowed: 0, up-1, up-2, up-3
-
tiltDefault: none - A slight rotation, a few degrees. Allowed: none, left, right
-
flowDefault: auto - The space between one thing and the next inside it, a step of the theme's scale: one space for everything, whatever the things are. auto keeps each element's own margins, which is what prose wants — a heading further from the paragraph above it than from the one below. Allowed: auto, 0, 1, 2, 3, 4, 5
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::card tone:accent shadow:lifted
### Founding plan
Everything, for the first hundred creators.
:::
:::inline
Items in a line that wraps: buttons, tags, logos, small facts.
Its items are separated by a --- line.
-
justifyDefault: start - How the line is distributed. Allowed: start, center, end, between
-
alignDefault: center - Vertical alignment within a line. Allowed: center, start, end
-
spaceDefault: 2 - The gap, a step of the theme's scale. Allowed: 1, 2, 3, 4
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::inline justify:center
[Start free](/signup)
---
[See pricing](/pricing)
:::
:::cover
Media cropped to a ratio, optionally in a device frame.
-
ratioDefault: 16/9 - The shape the image or video is cropped to. Allowed: 16/9, 16/10, 3/2, 4/3, 5/4, 1/1, 4/5, 3/4, 2/3, 9/16, 2/1, 21/9
-
focusDefault: center - Which part of the media stays in view when it is cropped. Allowed: center, top, bottom, left, right
-
frameDefault: rounded - none, rounded corners, a circle (avatars), a browser window or a phone around the media. Allowed: none, rounded, circle, browser, phone
-
shadowDefault: none - A shadow under the media. Allowed: none, soft, lifted
-
offsetDefault: 0 - Pull the element up into the content above it, in steps of the scale. Allowed: 0, up-1, up-2, up-3
-
tiltDefault: none - A slight rotation, a few degrees. Allowed: none, left, right
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::cover ratio:16/9 frame:browser shadow:lifted

:::
:::overlay
Content placed over its parent and kept inside it: a badge on a picture, or — with kind:plain — anything at all, a card over a photo, a caption, a play button.
-
atDefault: center - Where on the parent it sits. Allowed: center, top-left, top-right, bottom-left, bottom-right, bottom
-
kindDefault: badge - badge draws it as a small pill, which is what a label on a picture wants. plain draws nothing of its own: whatever is inside — a card, a heading, a button — sits over the parent as it is, never larger than the parent, scrolling inside itself if it would be. Allowed: badge, plain
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::cover ratio:4/3

:::overlay at:top-right
**New**
:::
:::
:::carousel
A horizontal strip of items that scrolls and snaps; no autoplay.
Its items are separated by a --- line.
-
itemDefault: normal - How wide each item is: about a quarter, a third or two thirds of the strip (wider on phones). Allowed: narrow, normal, wide
-
itemsDefault: plain - card draws each item as a card. Allowed: plain, card
-
spaceDefault: 3 - The gap, a step of the theme's scale. Allowed: 1, 2, 3, 4
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::carousel item:narrow items:card
"Best tool I adopted this year." — Ana
---
"It replaced three apps." — Bia
:::
:::masonry
Items of different heights packed into columns, like a photo wall. Reading order runs down each column.
Its items are separated by a --- line.
-
minDefault: 16 - The narrowest a column may get, in rem. Allowed: 12, 14, 16, 18, 20, 24
-
itemsDefault: plain - card draws each item as a card. Allowed: plain, card
-
spaceDefault: 3 - The gap, a step of the theme's scale. Allowed: 1, 2, 3, 4
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
motionDefault: none - How it appears as the reader scrolls to it; items of a layout arrive one after another. Nothing moves for a reader who asks for reduced motion, and without JavaScript everything is simply there. Allowed: none, fade, rise, scale
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::masonry min:14 items:card
"Short quote." — Ana
---
A longer testimonial that takes more lines than the others.
:::
:::marquee
A strip that scrolls by itself, for logos or short quotes. It pauses on hover and stands still for a reader who asks for reduced motion.
Its items are separated by a --- line.
-
speedDefault: normal - How fast the strip moves. Allowed: slow, normal, fast
-
directionDefault: left - Which way it moves. Allowed: left, right
-
spaceDefault: 4 - The gap between items, a step of the theme's scale. Allowed: 1, 2, 3, 4, 5
-
hideDefault: none - Hide on narrow screens (phones) or on wide ones, to show a different arrangement for each. Allowed: none, narrow, wide
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::marquee speed:slow

---

---

:::
:::banner
A band pinned to an edge of the screen — a cookie notice, an announcement, a promotion — with anything inside. Without a script it is a band at the end of the page, where it was written; with one it floats, and can be closed.
Its items are separated by a --- line.
-
positionDefault: bottom - Where it sits once a script pins it: along the bottom edge, along the top, in the middle over the dimmed page (where the reader answers before going on), or as a card in the bottom corner. Allowed: bottom, top, center, corner
-
shapeDefault: flat - flat runs edge to edge; floating is a card with a margin, the theme's corners and a shadow. The middle and the corner are always a card. Allowed: flat, floating
-
dismissDefault: none - Whether the reader may close it without answering: never; until the page is opened again; or for good, remembered on this site by the band's id. A `@consent` inside closes it when answered, whatever this says. Allowed: none, once, remember
-
surfaceDefault: default - The band's ground, with contrast-checked text. Allowed: default, soft, inverse
-
widthDefault: wide - How wide the band's content may get. Allowed: wide, full
-
id - A name for this block, so a link can land on it (`[Spaces](#spaces)`) and an agent can address it. Written as the element's id, never as a class. Without one, a link to a heading inside a band lands on the heading — halfway down its column in a split, with the picture cut off above it. Allowed: letters, numbers, dashes and underscores, starting with a letter or a number
Example
:::banner dismiss:remember surface:inverse id:cookies
Este site usa vídeos do YouTube, que carregam cookies do Google.
---
[Saiba mais](/privacidade)
:::
:::slot
In a template (a page other pages wear): where the wearing page goes. Everything around it — a nav, a side column, a footer — is what those pages have in common. A named slot holds a default that a page may replace with :::fill.
-
nameDefault: main - main is where the page's own content goes, and a template needs one. The others are places a page may fill; what is written inside the slot is what shows when it does not. Allowed: main, hero, aside, top, bottom, cta
Example
:::nav
**[Studio](~)**
---
- [Work](~/work)
- [About](~/about)
:::
:::slot
:::
:::slot name:cta
## Let's talk
[Write to us](~/contact)
:::
:::fill
In a page that wears a template: what goes into one of the template's named slots instead of its default. It leaves the page's own flow and shows where the template put that slot.
-
nameDefault: aside - The slot to fill. One the template does not have stays where it was written, so nothing a person wrote disappears. Allowed: hero, aside, top, bottom, cta
Example
:::fill name:cta
## Hiring designers
[See the roles](~/jobs)
:::
# The page's own content