Building Accessible,
On-Brand Documents
with Quarto

R/Medicine Demo

Charlotte Wickham

2026-05-05

Slides

Hello, I’m Charlotte Wickham

Slides

Motivation

Accessible

Reach

Technical standards: WCAG 2.0 AA, WCAG 2.1 AA, PDF UA-1

On-brand

Trust

Fonts
Logos
Colors
Tone

Demo

Start with 01-demo.qmd

  1. Add brand

  2. Check accessibility

  3. Customize appearance

What about code? Later…

Add a brand

From an external repository:

Terminal
quarto use brand cwickham/arcadonia-brand

Quarto: Preview (HTML)

Quarto: Preview Format… (Typst (PDF))

Applies typography, colors, and logo (typst only)

Update? Run quarto use brand again.

Brand components

cwickham/arcadonia-brand

_brand.yml
# Arcadonia Health Department brand
# A fictional public-health agency

meta:
  name: Arcadonia Health Department
  link: https://example.org/arcadonia-health

logo:
  images:
    seal:
      path: images/ahd-seal.svg
      alt: Arcadonia Health Department seal
    wordmark:
      path: images/asr-wordmark.svg
      alt: Arcadonia Health Department Arcadonia Surveillance Reports
  small: wordmark
  medium: wordmark
  large: wordmark

color:
  palette:
    forest: "#1f4d2e"
    forest-dark: "#0f2e1a"
    forest-light: "#5B9573"
    cream: "#f5eee8"
    ink: "#1a1a1a"
    rust: "#b8511f"
  background: cream
  foreground: ink
  primary: forest
  
typography:
  fonts:
    - family: Literata
      source: google
      weight: [400, 500, 700]
    - family: Public Sans
      source: google
      weight: [400, 700]
  base:
    family: Public Sans
    size: 12pt
  headings:
    family: Literata
    weight: 500
    color: primary
  link:
    color: forest-light
    decoration: underline

defaults:
  bootstrap:
    defaults:
      callout-color-note: $brand-forest

Check accessibility: HTML

To see results in the document:

01-demo.qmd
---
format:
  html:
    axe:
      output: document
---

Tip

Remember to remove axe before publishing!

Uses axe-core to check WCAG 2.0 Level A & AA, WCAG 2.1 Level A & AA & Best Practices

Check accessibility: Typst (PDF)

01-demo.qmd
---
format:
  typst:
    pdf-standard: ua-1
---

Checks against PDF/UA-1:

  1. Within Typst
  2. On resulting PDF with veraPDF, e.g. against PDF/UA-1 ruleset
Terminal
quarto install verapdf

Brand tweaks

Fix upstream in cwickham/arcadonia-brand:

_brand.yml
typography:
  link:
    color: forest

Override in document options (or _quarto.yml):

report.qmd
---
linkcolor: "#1f4d2e"
---

Brand tweaks: CSS/SCSS

report.qmd
---
format:
  html:
    theme: [custom.scss, brand]
---
custom.scss
/*-- scss:defaults --*/
$link-color: $brand-forest;

/*-- scss:rules --*/
h2 {
  border: none;
}

Brand tweaks: Typst rules

report.qmd
```{=typst}
{{< include typst-style.typ >}}
```


typst-style.typ
#show link: set text(fill: brand-color.forest)  
#show ref: set text(fill: brand-color.forest)
#show ref: it => underline(it)   
#show heading: set block(above: 1.5em, below: 1em)  

Control layout: Partials

report.qmd
---
format:
  typst:
    template-partials:
      - partials/typst-template.typ
      - partials/page.typ
      - partials/typst-show.typ
---

Preview of PDF output showing a header with the Arcadonia Health Department seal and report title, and a footer with page number and report generation date.

Code Outputs

02-with-code.qmd a report with a ggplot2 plot and gt table.

Problem: code outputs don’t automatically use brand fonts or colors.

Preview of code outputs showing a ggplot2 plot and a gt table.

Access brand via brand.yml package

Access brand in R:

library(brand.yml)
brand <- read_brand_yml()
brand

Extract components:

base_family <- brand$typography$base$family
ink <- brand$color$foreground
paper <- brand$color$background

Apply brand using package specific functions

ggplot2

# ggplot2 
... +
  theme_minimal(             
    base_size = 12,
    base_family = base_family,
    ink = ink,
    paper = paper
  ) 

gt

# gt 
... |>
  theme_brand_gt() |> # helper from `brand.yml` package
  opt_table_font(base_family, weight = "regular", add = FALSE) 

Branded outputs

HTML

HTML preview of the branded tetanus surveillance report.

PDF

PDF preview of the branded tetanus surveillance report.

Accessibility in practice

Screenshot of a gt table with an accessibility violation highlighted by axe-core.

Authoring accessible documents

Authoring in .qmd naturally encourages:

  • Using semantic structure (but don’t skip heading levels)
  • A reading order

Accessibility checks will catch some problems:

  • Missing alternative text (always set fig-alt)
  • Contrast of text and background in format: html

Automatic checks aren’t enough

  • Is your alt text meaningful?
  • Does the PDF tagging structure reflect logical structure?
  • Are charts readable under color-vision deficiencies?
  • Are tables coherent under cell-by-cell navigation?
  • Can a real person who relies on assistive tech actually use this?

Accessibility is a shared responsibility

A reader reports an issue with a table in your PDF when using VoiceOver in Adobe Acrobat Reader.

The “fix” might live in:

Your code gt knitr Quarto Pandoc Typst Adobe Acrobat Reader VoiceOver

Expect work-arounds for now — and improvement as more people test and report.

Questions?

What about PDF via LaTeX?

pdf-standard also works for pdf:

format:
  pdf:
    pdf-standard: ua-2 # <- PDF/UA-2 

(But, no brand support for pdf…)