Semantic layouts

The overview below links to each definition. Function definitions show signatures with parameter and return types; variables show their declared types. Descriptions and defaults follow.

author

Creates a validated author record for setup(authors:) and layouts.title(authors:).

A name on its own needs no record at all. authors: takes content or a string wherever it takes a record, so authors: [Ada Lovelace] and authors: ([Ada Lovelace], [Charles Babbage]) are both complete author lists. Reach for author() when a name carries more than itself:

#let ada = mosaic.layouts.author(
  [Ada Lovelace],
  affiliations: ([Analytical Society], [University of London]),
  email: "ada@example.org",
  orcid: "0000-0002-1825-0097",
  corresponding: true,
)

Affiliations

An affiliation is the institution itself: content or a non-empty string. Two authors share one legend number exactly when they give the same affiliation, so bind a shared institution once and reuse the binding:

#let lon = [University of London]
#let ada = mosaic.layouts.author([Ada Lovelace], affiliations: (lon,))
#let bab = mosaic.layouts.author([Charles Babbage], affiliations: (lon,))

The academic title variant renders these as superscript numbers over a numbered legend. Compact variants list them without numbering.

Validation

Values are checked at construction rather than at render time:

  • email must look like an address.
  • orcid must be a well-formed iD.
  • corresponding requires at least one of email or orcid.
Signature
author(
  name: content | str,
  affiliations: array = (),
  email: str | none = none,
  orcid: str | none = none,
  corresponding: bool = false
) -> dictionary
Parameters
  • name

    • Type: content or str
    • The author’s name, as the sole positional argument.
  • affiliations

    • Type: array
    • Default: ()
    • Array of institutions, as content or non-empty strings, in the order they should be listed for this author.
  • email

    • Type: str or none
    • Default: none
    • Contact address, shown on the academic title variant and linked as a mailto:. Independent of orcid.
  • orcid

    • Type: str or none
    • Default: none
    • ORCID iD in 0000-0000-0000-0000 form, rendered as a linked ORCID label beside the name on every title variant. Independent of email.
  • corresponding

    • Type: bool
    • Default: false
    • Whether to mark this author as the corresponding one, with an asterisk beside the name and on the contact line. Requires email or orcid.

content

Creates a conventional header, body, and footer grid recipe.

This is the ordinary slide layout, and the one automatic level-two headings resolve to. It builds a vertical Mosaic split whose body child is a horizontal split of plain cells.

#mosaic.slide(
  layout: mosaic.layouts.content(variant: "header-body", columns: 2),
  [== Two columns],
  [Left body],
  [Right body],
)

Cells

The surrounding mosaic.slide fills cells in traversal order:

  • header, when the variant includes one.
  • body, or body-1, body-2, and so on when columns is above one.
  • footer, when the variant includes one.

A setup-level content: (footer: ...) default can satisfy the footer, so a positional slide may omit that final block.

Variants

  • body: one region, edge to edge.
  • header-body: a content-sized header above the body.
  • body-footer: the body above a content-sized footer.
  • header-body-footer: both. The default.

Labels

Every resolved cell carries a label, so appearance comes from native Typst rules:

  • mosaic-cell-header: the header, in the variants that include one.
  • mosaic-cell-body: the body, when columns is one.
  • mosaic-cell-body-1, mosaic-cell-body-2, and so on: the body columns, when columns is above one.
  • mosaic-cell-footer: the footer, in the variants that include one.

Styling

The layout is purely structural, so its looks come from rules on those labels.

#show label("mosaic-cell-header"): mosaic.surface(fill: luma(240))

The header cell carries no special typography of its own. Put a native level-two heading in its content to style it as a heading and register it with outlines.

Signature
content(
  variant: str = "header-body-footer",
  columns: int = 1,
  tracks: auto | array = auto
) -> dictionary
Parameters
  • variant

    • Type: str
    • Default: "header-body-footer"
    • Structural arrangement: body, header-body, body-footer, or header-body-footer.
  • columns

    • Type: int
    • Default: 1
    • Number of body columns, and therefore the number of body blocks the slide must supply. Must be a positive integer.
  • tracks

    • Type: auto or array
    • Default: auto
    • Native Typst track sizes for the body columns, one per column. auto splits the body evenly.

      mosaic.layouts.content(columns: 2, tracks: (2fr, 1fr))

image

Creates an image-first grid recipe.

This is the image-first counterpart to layouts.content: the picture is the argument rather than slide content, and the text regions arrange around it. The surrounding mosaic.slide fills only the text cells.

#mosaic.slide(
  layout: mosaic.layouts.image(
    path("chart.webp"),
    caption: [Revenue by quarter],
  ),
  [== Results],
)

Variants

  • figure: a contained picture centered under a header cell, with an optional caption below it. The conventional academic figure slide, and the default.
  • left, right, top, bottom: a full-bleed picture paired with a text region of header and body cells, sized by tracks.
  • full: the picture behind a single body cell, so text reads over the photograph. Put a heading inside the body to title it, or pass an empty block for a bare full-bleed slide.

Captions

A caption composes a native Typst figure around the picture, so it takes the deck’s own show figure.caption styling and figure numbering. Switch the numbering off with an ordinary set figure(numbering: none). Captions are accepted by the figure variant only.

Labels

Every resolved cell carries a label, so appearance comes from native Typst rules:

  • mosaic-cell-header: the header, in the figure and directional variants.
  • mosaic-cell-body: the text region, in the directional and full variants.
  • mosaic-cell-image: the picture, in the figure and directional variants. The full variant paints the picture as the body cell’s background instead, so it has no image cell of its own.

Styling

The layout is purely structural, so its looks come from rules on those labels. The full variant inherits the surrounding native text color, so quiet the photograph with the image dictionary’s scrim key and override the cell’s text fill.

#show label("mosaic-cell-body"): set text(fill: white)
#mosaic.slide(
  layout: mosaic.layouts.image(
    (path: "photo.webp", scrim: black.transparentize(55%)),
    variant: "full",
  ),
  [== Full bleed],
)
Signature
image(
  image: content | str | path | dictionary,
  variant: str = "figure",
  caption: content | none = none,
  fit: auto | str = auto,
  tracks: auto | length | ratio | relative | fraction | array = auto
) -> dictionary
Parameters
  • image

    • Type: content or str or path or dictionary
    • The picture the slide is built around, as the sole positional argument. Give a path, ready-made content, or a dictionary whose scrim key paints a layer over the picture and under any text composed on top of it.
  • variant

    • Type: str
    • Default: "figure"
    • Structural arrangement of picture and text: figure, full, left, right, top, or bottom.
  • caption

    • Type: content or none
    • Default: none
    • Caption composed below a figure picture. Rejected by the other variants.
  • fit

    • Type: auto or str
    • Default: auto
    • How the picture fills its region.

      • "contain": fit the whole picture inside the region. The figure default, since a chart must never be cropped.
      • "cover": fill the region, cropping the overhang. The default for every other variant.

      auto picks the per-variant default above.

  • tracks

    • Type: auto or length or ratio or relative or fraction or array
    • Default: auto
    • Sizes the split of a directional variant, and is rejected by figure and full. One native Typst track size answers “how much room does the picture get” and is side-independent, so left and right stay mirror images without reordering anything; the text region takes the remaining 1fr. An array of two is in visual order instead, and must be mirrored by hand when the variant flips.

title

Creates a presentation title grid.

The layout supplies every cell’s content itself, so the surrounding mosaic.slide consumes no slide bodies.

#show: mosaic.setup.with(
  title: [Tree-based slide grids],
  subtitle: [A layout model for Typst],
  authors: [Ada Lovelace],
  date: [2026-08-03],
)

#mosaic.slide(layout: "title", variant: "centered")

Inheritance

Each of title, subtitle, authors, and date defaults to auto, which takes the value configured on setup. To override an inherited value:

  • Pass explicit content or a string to replace it.
  • Pass none to suppress an inherited title, subtitle, or date.
  • Pass () to suppress inherited authors.

Variants

Text variants:

  • centered: the heading stack at the slide’s center, details anchored to the bottom edge.
  • bordered: a thin rule border inset from the slide edge with the centered stack inside it.
  • ruled: the heading stack over a full-width accent rule with the details beneath, flush left at the slide’s vertical center. The beamer-metropolis title page, and the default.
  • kicker: the magazine masthead. A strong opening rule, the subtitle set as a small tracked-caps eyebrow in the accent color, the title below it, and the details anchored to the bottom edge.
  • panel: a vertical side panel in the deck’s text color carries the details, knocked out in the canvas color under a short accent rule; the heading stack takes the main field.
  • academic: the conference-poster arrangement. Author names carry superscript affiliation numbers over a numbered affiliation legend and a contact line. Requires at least one author.

One image variant, which requires image and reads position:

  • image with position: "left", "right", "top", or "bottom" (the default is "left"): a full-bleed picture beside or above the title stack, sized by tracks.

A full-slide photographic title is not a variant: give the slide a background: plane and compose the type yourself, reading the deck’s own metadata back through info().

To invert any of these, with the slide ground in the deck’s text color and the type knocked out, pass invert: true on the slide rather than picking a variant; inversion is a polarity, not a structure.

Authors

Every variant accepts the same authors, written in whichever of three spellings fits the deck: one name as content or a string, an array of names, or an array of records built with layouts.author for the authors that carry affiliations, an ORCID iD, or an address. Names and records mix freely in one array. Every variant renders every author field through the same tiers: a byline of names with linked ORCID labels, superscript affiliation numbers, and the corresponding asterisk, then one fine-print line per kind of information: the numbered affiliation legend, the contact addresses, the date. Kinds never share a line, and the superscript markers appear exactly when the deck names more than one institution.

Labels

Every resolved cell carries a label, so appearance comes from native Typst rules:

  • mosaic-cell-title: the title stack, in every variant. Most variants compose the subtitle and the details inside it too.
  • mosaic-cell-details: the affiliation and date band, in the panel and academic variants, which set those tiers outside the title cell.
  • mosaic-cell-authors: the byline, in the academic variant.
  • mosaic-cell-image: the picture, in the image variant.

One further label is not a cell: the display line of the title stack carries mosaic-title-display, which is where a theme states the title’s display size.

Styling

The layout is structural. A rule on <mosaic-cell-title> reaches the whole composed stack: title, subtitle, and details alike. Recoloring it is what light-on-dark compositions over a photograph need.

#show label("mosaic-cell-title"): set text(fill: white)
#mosaic.slide(
  layout: "title",
  background: mosaic.components.image("cover.webp", scrim: black.transparentize(55%)),
)

Sizing it works the same way, because the display line carries its own <mosaic-title-display> label and the theme’s display size lands there rather than on the cell. The tiers below are ordinary ems of the cell, so one rule scales the stack as a unit and the proportions hold. That is how to ask for quiet type in the corner of a photograph.

#show label("mosaic-cell-title"): set text(size: 0.45em)

A theme states the display size on the inner label instead, which leaves the outer one free for the deck to scale:

#show label("mosaic-title-display"): set text(size: 2em, weight: "semibold")
Signature
title(
  title: auto | content | str = auto,
  subtitle: auto | content | str | none = auto,
  date: auto | content | str | none = auto,
  image: none | content | str | path | dictionary = none,
  variant: str = "ruled",
  position: auto | str = auto,
  authors: auto | content | str | array = auto,
  tracks: auto | length | ratio | relative | fraction | array = auto,
  rule: auto | bool = auto,
  accent: color | auto = auto
) -> dictionary
Parameters
  • title

    • Type: auto or content or str
    • Default: auto
    • Title text. auto inherits setup(title:).
  • subtitle

    • Type: auto or content or str or none
    • Default: auto
    • Subtitle set tight below the title. auto inherits setup(subtitle:); none suppresses it.
  • date

    • Type: auto or content or str or none
    • Default: auto
    • Display date joined into the fine-print details line. auto inherits setup(date:); none suppresses it.
  • image

    • Type: none or content or str or path or dictionary
    • Default: none
    • The picture used by the image variant, and rejected by the others. Give a path, ready-made content, or a dictionary whose scrim key quiets the photograph enough to read text over it, as in (path: "cover.webp", scrim: black.transparentize(55%)).
  • variant

    • Type: str
    • Default: "ruled"
    • Structural arrangement: ruled, centered, bordered, kicker, panel, academic, or image.
  • position

    • Type: auto or str
    • Default: auto
    • Where the image variant’s picture sits, and rejected by the others: left, right, top, or bottom, for a full-bleed picture beside or above the title stack. auto means left.
  • authors

    • Type: auto or content or str or array
    • Default: auto
    • One name, or an array of names and records created with layouts.author. auto inherits setup(authors:); () suppresses an inherited list.
  • tracks

    • Type: auto or length or ratio or relative or fraction or array
    • Default: auto
    • Sizes the image variant’s split, and is rejected elsewhere. One native Typst track size sizes the picture and is side-independent, so the left and right positions stay mirror images; the title region takes the remaining 1fr. An array of two is in visual order instead, and must be mirrored by hand when the position flips. auto gives the picture the smaller share.
  • rule

    • Type: auto or bool
    • Default: auto
    • Whether to draw the variant’s structural mark: the ruled full-width rule, the bordered border, or the kicker opening rule. On the image variant it draws the short accent rule of the compact stack instead. auto draws the structural marks and omits the accent rule on the image variant, where the photograph already does that work.
  • accent

    • Type: color or auto
    • Default: auto
    • Color of the variant’s structural mark. auto uses the deck’s text color for the marked text variants (bordered, kicker) and the semantic accent for the image variant’s short rule.

section

Creates a section divider grid.

The section cell’s text is the slide’s own content, so the surrounding mosaic.slide supplies one block. Automatic level-one headings resolve to this layout.

#mosaic.slide(
  layout: "section",
  number: [02],
  subtitle: [How the grid resolves],
)[Structure]

Variants

  • plain: one centered section cell. The default.
  • rule: a heavy full-width rule with the title hanging beneath it, flush left, the number above the rule.
  • numeral: the section number set enormous in the line color, bleeding off the top-right edge behind a lower-left title stack.
  • baseline: title flush left and number flush right sharing one baseline, tied together by a full-width hairline.
  • toc: every section in the deck listed, the current one alive with its number, the others ghosted.
  • image-left, image-right, image-top, image-bottom: that cell beside or above a full-bleed image cell, sized by tracks.
  • image-background: the section text directly over a full-slide picture.

Every image variant requires image. The designed text variants (every variant but plain and the image ones) treat an omitted number as the automatic section counter, so they need no argument in the ordinary case.

Labels

Every resolved cell carries a label, so appearance comes from native Typst rules:

  • mosaic-cell-section: the section text, in every variant. The number and subtitle are composed inside it, so one rule reaches the whole stack.
  • mosaic-cell-image: the picture, in the directional image variants. The image-background variant paints the picture as the section cell’s background instead, so it has no image cell of its own.

Styling

The layout is structural. The centered arrangement and title typography come from the <mosaic-cell-section> label rules setup emits. Over a photograph the text inherits the surrounding native text color, so quiet the picture with the image dictionary’s scrim key and override the cell’s text fill.

#show label("mosaic-cell-section"): set text(fill: white)
#mosaic.slide(
  layout: "section",
  variant: "image-background",
  image: (path: "cover.webp", scrim: black.transparentize(55%)),
)[Structure]
Signature
section(
  subtitle: content | str | none = none,
  number: content | str | none = none,
  image: none | content | str | path | dictionary = none,
  variant: str = "plain",
  accent: color | auto = auto,
  tracks: auto | length | ratio | relative | fraction | array = auto
) -> dictionary
Parameters
  • subtitle

    • Type: content or str or none
    • Default: none
    • Optional subtitle set below the section title.
  • number

    • Type: content or str or none
    • Default: none
    • Optional section number or label. plain and the image variants set it above the title and omit it when none; the designed text variants build their composition around it and read the automatic section counter when it is none.
  • image

    • Type: none or content or str or path or dictionary
    • Default: none
    • The picture used by the image variants, and rejected by the others. Give a path, ready-made content, or a dictionary whose scrim key quiets the photograph enough to read text over it.
  • variant

    • Type: str
    • Default: "plain"
    • Structural arrangement: plain, image-left, image-right, image-top, image-bottom, or image-background.
  • accent

    • Type: color or auto
    • Default: auto
    • Color used by the optional section number. auto inherits the semantic muted color resolved by setup, so numbers stay subordinate to the title; pass a color to override.
  • tracks

    • Type: auto or length or ratio or relative or fraction or array
    • Default: auto
    • Sizes the split of a directional image variant, and is rejected by the others. One native Typst track size sizes the picture and is side-independent, so image-left and image-right stay mirror images; the section region takes the remaining 1fr. An array of two is in visual order instead.