my-brand
|-- README.md
|-- _extensions
| `-- my-brand
| |-- _extension.yml
| `-- brand.yml
|-- _quarto.yml
`-- example.qmd
2 directories, 5 files
Session 5
Saturday, the 7th of February, 2026
This session explores Quarto’s advanced theming and branding capabilities, covering Bootstrap 5 customisation, brand.yml systems for unified branding, Pandoc templating syntax, and Typst customisation for professional PDF output.
By the end of this session, participants will be able to:
brand.yml.Quarto HTML format uses Bootstrap 5, providing:
Available themes: default, cerulean, cosmo, cyborg, darkly, flatly, journal, litera, lumen, lux, materia, minty, morph, pulse, quartz, sandstone, simplex, sketchy, slate, solar, spacelab, superhero, united, vapor, yeti, zephyr.
See HTML Theming for more.
Can also be written as:
yaml
See HTML Theming - Basic Options for more.
Move to SCSS for more control:
Custom SCSS file follows a specific structure using comments:
styles.scss
See More About Quarto Themes for more.
brand.yml Foundationbrand.yml is a single YAML file that codifies your organisation’s brand guidelines into a format that can be used by Quarto (but not limited to) to create branded outputs across multiple formats.
Key benefits:
brand.yml StructureCreate a _brand.yml file in your project root:
_brand.yml
meta:
name: "Your Organisation"
link: "https://yourorg.com"
color:
palette:
primary: "#2E86AB"
secondary: "#A23B72"
light: "#F8F9FA"
dark: "#343A40"
primary: primary
foreground: dark
background: light
logo:
small: "assets/logo-small.png"
medium: "assets/logo-medium.png"
large: "assets/logo-large.png"
typography:
fonts:
- family: "Inter"
source: "google"
base: "Inter"
headings: "Inter"The palette defines named colours that can be referenced throughout your brand:
_brand.yml
Cross-format usage:
$brand-primary (SCSS), --brand-primary (CSS), etc.brand-color.primary, etc.Define your organisation’s font system:
yaml
typography:
fonts:
# Google Fonts (automatically loaded)
- family: "Inter"
source: "google"
weight: [300, 400, 500, 600, 700]
# System fonts (fallback)
- family: "system-ui"
source: "system"
# Font assignments
base: "Inter" # Body text
headings: "Inter" # All headings
monospace: "SF Mono" # Code blocksSee Typst Brand YAML for troubleshooting fonts in Typst.
Provide logos at different sizes for various contexts:
| Format | Location | Logo Preference (high to low) |
|---|---|---|
html/dashboard |
Top navigation bar | small > medium > large |
html |
Side navigation | medium > small > large |
typst |
Top left, control with format: typst: logo |
medium > small > large |
revealjs |
Bottom right corner of slides | medium > small > large |
website/book project |
favicon shown in browser tab |
small |
See Logo Configuration for more.
| Format | Location | Logo Preference (high to low) |
|---|---|---|
html/dashboard |
Top navigation bar | small > medium > large |
html |
Side navigation | medium > small > large |
typst |
Top left, control with format: typst: logo |
medium > small > large |
revealjs |
Bottom right corner of slides | medium > small > large |
website/book project |
favicon shown in browser tab |
small |
See Logo Configuration for more.
Combine brand.yml with Bootstrap customisation:
brand.yml or SCSS for component customisation.
Note
The brand colours become available as CSS variables and SCSS variables automatically.
Brand extensions are Quarto extensions that provide a brand.yml file and its assets, packaged for easy distribution and reuse.
Key features:
This creates:
my-brand
|-- README.md
|-- _extensions
| `-- my-brand
| |-- _extension.yml
| `-- brand.yml
|-- _quarto.yml
`-- example.qmd
2 directories, 5 files
_extensions/my-brand/brand.yml
meta:
name: "My Organisation"
link: "https://myorg.com"
color:
palette:
# Primary brand colours
brand-blue: "#2E86AB"
brand-coral: "#A23B72"
brand-gold: "#F4A261"
# Supporting colours
neutral-light: "#F8F9FA"
neutral-dark: "#343A40"
success-green: "#28A745"
warning-amber: "#FFC107"
# Semantic mappings
primary: brand-blue
secondary: brand-coral
success: success-green
warning: warning-amber
foreground: neutral-dark
background: neutral-light
logo:
small: assets/logo/favicon.png
medium: assets/logo/logo-horizontal.png
large: assets/logo/logo-vertical.png
typography:
fonts:
- family: "Source Sans Pro"
source: "google"
weight: [300, 400, 600, 700]
base: "Source Sans Pro"_extensions/my-brand/brand.yml
defaults:
bootstrap:
defaults:
# Enhanced navigation
navbar-padding-y: 1rem
navbar-brand-font-size: 1.5rem
# Improved buttons
btn-padding-y: 0.5rem
btn-padding-x: 1.5rem
btn-font-weight: 600
# Better spacing
spacer: 1rem
rules: |
/* Professional enhancements */
.navbar-brand {
font-weight: 700;
}
.btn-primary {
border-radius: 2rem;
transition: all 0.3s ease;
}
.btn-primary:hover {
transform: translateY(-1px);
}
/* Content styling */
.title-block-header {
padding: 3rem 2rem;
margin-bottom: 2rem;
border-radius: 0.5rem;
}Organise brand assets:
example.qmd
---
title: "Brand Extension Showcase"
subtitle: "Demonstrating consistent branding"
author: "Your Name"
format:
html:
theme:
- quartz
- brand
---
# Welcome to Our Brand System
This document demonstrates the power of brand extensions in Quarto.
[Primary Action]{.btn .btn-primary}
[Secondary Action]{.btn .btn-secondary}Important
Brand extensions require a _quarto.yml project file to work.
Objective: Create a comprehensive brand extension that demonstrates unified branding across formats using brand.yml and light CSS customisation.
Example Code:
Generate extension scaffold:
Define your brand identity.
Add styling.
Build test project:
Test across formats:
Verify brand consistency.
✅ You’ve successfully completed the exercise if you can:
brand.yml and light (S)CSS.Quarto uses Pandoc’s templating system to generate output.
Key concepts:
$variable$ inserts YAML metadata.$if(variable)$...$endif$ for optional content.$for(variable)$...$endfor$ for repeated content.See Pandoc Template Syntax for complete documentation.
Variables from YAML front matter are inserted using $variable$:
Tip
Use $variable$ in any template file (.typ, .tex, .html, etc.).
See Article Templates for templates and partials.
Show content only when a variable exists:
Note
Use $if(variable)$...$else$...$endif$ for alternative content.
Important
$if(variable)$ in Pandoc templates checks if a variable is:
Process lists from YAML metadata:
Note
Use $it$ to reference the current item in a loop. Use $sep$ followed by the separator string for separators.
Add separators between items:
Objective: Modify a partial template to display additional metadata using Pandoc templating syntax.
Example Code:
Retrieve the partials described in Article Templates
Modify the title slide partial from Reveal.js to underline the corresponding author:
$if(by-author)$ to check for by-author metadata.by-author to find the corresponding author and underline their name.Add additional metadata to the title slide, such as affiliations or ORCID IDs.
Test the changes by rendering a sample presentation with multiple authors with affiliations and a corresponding author.
✅ You’ve successfully completed the exercise if you can:
Typst is a modern typesetting system for creating beautiful PDFs, designed to be simpler than LaTeX.
Why Typst?
See Typst Basics for more.
Quarto’s Typst templates use two key files:
typst-template.typ - Defines document layout:typst-template.typ
typst-show.typ - Captures YAML metadata using Pandoc syntax:typst-show.typ
by-author to get Quarto’s extended author metadata.
Note
Notice the Pandoc template syntax: $if()$, $for()$, $variable$.
typst-template.typ
This creates:
my-format
|-- README.md
|-- _extensions
| `-- my-format
| |-- _extension.yml
| |-- typst-show.typ
| `-- typst-template.typ
`-- template.qmd
2 directories, 5 files
Tip
Modify the generated typst-template.typ file to customise your layout.
brand.ymltypst-show.typ
Objective: Create a custom format extension that bundles brand.yml and styling into a reusable format for your organisation.
Example Code:
Generate format extension scaffold:
Add brand.yml and configure extension in _extension.yml`:
Define your template in typst-template.typ and typst-show.typ.
Use your format in template.qmd:
Render and verify:
Add HTML output to your format:
Add HTML format to _extension.yml.
Create/Modify simple template. (See HTML partials)
Test both formats:
✅ You’ve successfully completed the exercise if you can: