Typst Setup & Brand Template Guide

Solanasis brand template for offline PDF generation using Typst + typst-py.


1. Overview

Typst is a modern markup-based typesetting system (MIT-licensed, v0.14.8+) that compiles .typ files to PDF. It provides LaTeX-quality output with a much simpler syntax, supporting custom fonts, precise page layout, headers/footers, and accessible PDF/UA-1 output. The Python binding typst-py enables programmatic PDF generation from Python scripts with variables injected via a sys_inputs dictionary. Solanasis uses Typst for offline branded PDF reports and security assessment documents where professional typography matters and internet access may not be available.


2. Installation (WSL2)

Install Typst CLI

curl -fsSL https://typst.community/typst-install/install.sh | bash

Verify installation:

typst --version

Install Python Binding

pip install typst

Verify Python binding:

python3 -c "import typst; print('typst-py OK')"

Font Setup

Solanasis brand fonts must be installed locally for Typst to use them:

mkdir -p ~/.local/share/fonts/solanasis
# Download from Google Fonts:
# - Playfair Display: https://fonts.google.com/specimen/Playfair+Display
# - Montserrat: https://fonts.google.com/specimen/Montserrat
# - Libre Baskerville: https://fonts.google.com/specimen/Libre+Baskerville
# Unzip TTF/OTF files into ~/.local/share/fonts/solanasis/
fc-cache -fv

Verify fonts are available to Typst:

typst fonts | grep -i "playfair\|montserrat\|libre"

3. Brand Template

The following Typst template specification applies Solanasis brand identity. Save this as solanasis-proposal.typ (or the appropriate template name for your document type).

Color Definitions

#let navy = rgb("#020532")
#let copper = rgb("#C47A3D")
#let parchment = rgb("#FEF9F1")
#let warm-stone = rgb("#F0EBE4")
#let charcoal = rgb("#111827")

Page Setup

#set page(
  paper: "us-letter",
  margin: (top: 1.2in, bottom: 1in, left: 1in, right: 1in),
  background: rect(fill: parchment, width: 100%, height: 100%),
)

Typography

#set text(font: "Montserrat", size: 11pt, fill: charcoal)
#show heading.where(level: 1): set text(font: "Playfair Display", fill: navy, size: 24pt)
#show heading.where(level: 2): set text(font: "Montserrat", weight: "bold", fill: copper, size: 16pt)
#set page(
  header: [],
  footer: [
    #line(length: 100%, stroke: 0.5pt + copper)
    #v(4pt)
    #text(size: 8pt, fill: navy)[Solanasis LLC | solanasis.com #h(1fr) Page #counter(page).display()]
  ],
)

Variable Injection

Typst supports variable injection from the CLI or Python via sys.inputs:

#let client_name = sys.inputs.at("client_name", default: "Client Name")
#let project_title = sys.inputs.at("project_title", default: "Project Title")
#let date = sys.inputs.at("date", default: "Date")
#let prepared_by = sys.inputs.at("prepared_by", default: "Dmitri Zasage, CEO")

Complete Template Example

Combining all sections above into a single solanasis-proposal.typ:

// -- Solanasis Brand Template --
// Usage: typst compile solanasis-proposal.typ output.pdf --input client_name="Acme Corp"
 
#let navy = rgb("#020532")
#let copper = rgb("#C47A3D")
#let parchment = rgb("#FEF9F1")
#let warm-stone = rgb("#F0EBE4")
#let charcoal = rgb("#111827")
 
#let client_name = sys.inputs.at("client_name", default: "Client Name")
#let project_title = sys.inputs.at("project_title", default: "Project Title")
#let date = sys.inputs.at("date", default: "Date")
#let prepared_by = sys.inputs.at("prepared_by", default: "Dmitri Zasage, CEO")
 
#set page(
  paper: "us-letter",
  margin: (top: 1.2in, bottom: 1in, left: 1in, right: 1in),
  background: rect(fill: parchment, width: 100%, height: 100%),
  footer: [
    #line(length: 100%, stroke: 0.5pt + copper)
    #v(4pt)
    #text(size: 8pt, fill: navy)[Solanasis LLC | solanasis.com #h(1fr) Page #counter(page).display()]
  ],
)
 
#set text(font: "Montserrat", size: 11pt, fill: charcoal)
#show heading.where(level: 1): set text(font: "Playfair Display", fill: navy, size: 24pt)
#show heading.where(level: 2): set text(font: "Montserrat", weight: "bold", fill: copper, size: 16pt)
 
// Title block
#align(center)[
  #text(font: "Playfair Display", size: 28pt, fill: navy)[#project_title]
  #v(8pt)
  #text(size: 14pt, fill: copper)[Prepared for #client_name]
  #v(4pt)
  #text(size: 12pt, fill: charcoal)[#prepared_by | #date]
]
#v(24pt)
#line(length: 100%, stroke: 0.5pt + copper)
#v(12pt)
 
// Document content starts here

4. Usage with typst-py (Python)

The typst-py Python binding compiles .typ files programmatically and returns PDF bytes:

import typst
 
pdf_bytes = typst.compile(
    "templates/solanasis-proposal.typ",
    sys_inputs={
        "client_name": "Acme Corp",
        "project_title": "Security Assessment Proposal",
        "date": "2026-04-12",
        "prepared_by": "Dmitri Zasage, CEO"
    },
    font_paths=["~/.local/share/fonts/solanasis/"]
)
 
with open("output/proposal.pdf", "wb") as f:
    f.write(pdf_bytes)

Key points:

  • sys_inputs values are accessible in the template via sys.inputs.at("key")
  • font_paths tells Typst where to find custom fonts (in addition to system fonts)
  • The function returns raw PDF bytes — write them to a file or pass to another tool
  • Compilation is fast (milliseconds, not seconds)

5. Usage with CLI

Basic compilation

typst compile template.typ output.pdf

With variables

typst compile template.typ output.pdf --input client_name="Acme Corp" --input date="2026-04-12"

With font path

typst compile template.typ output.pdf --font-path ~/.local/share/fonts/solanasis/

Watch mode (for development)

Auto-recompiles on file changes — useful when iterating on template design:

typst watch template.typ output.pdf

6. Integration with solanasis-scripts

  • Future generate-doc.py enhancement could add --engine typst flag alongside the existing GWS CLI engine, enabling offline PDF generation as an alternative pipeline
  • Brand constants in the .typ template mirror the Python constants in generate-pitch-deck.py (Navy #020532, Copper C47A3D, Parchment FEF9F1, Warm Stone F0EBE4, Charcoal #111827)
  • Typst templates should live in solanasis-scripts/templates/typst/ directory
  • Follow CLI conventions from solanasis-scripts/docs/cli-conventions.md (argparse, —dry-run, —check-only) for any wrapper scripts

7. Troubleshooting

”Font not found”

Typst cannot locate the specified font. Rebuild the font cache and verify:

fc-cache -fv
typst fonts | grep FontName

Ensure the font TTF/OTF files are in ~/.local/share/fonts/solanasis/ or pass --font-path explicitly.

”typst-py import error”

The Python binding is not installed in the active environment. Verify:

which python3
pip show typst

Ensure pip install typst was run in the correct virtual environment.

”sys.inputs not available”

The sys.inputs feature requires Typst 0.11 or newer. Update to the latest version:

curl -fsSL https://typst.community/typst-install/install.sh | bash
typst --version

8. References