Slide writer
Use when building a slide deck in Typst + Touying for a scientific talk, lecture, or project briefing — ships a browsable zoo of color themes, layout templates, and gadgets (callouts, theory boxes, CeTZ diagrams, pin annotations) that compose into projector-safe slides. Distinct from slide-writing (HTML, QudeLeap brand) and paper-writer (full manuscripts).From its SKILL.md
npx -y skills add QuantumBFS/sci-brain --skill slide-writerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
11.5 KB, as published. Nobody here has run it
Slide Writer (Typst + Touying)
A technical skill for building PDF slide decks in Typst with the Touying slide engine. It ships a zoo — five color themes, nine layout templates, and two dozen gadgets — that compose into projector-safe slides for scientific talks. The zoo is the deliverable; this file teaches how to drive it.
Scope note. This skill is the technical companion to slide-writing.
slide-writing owns the logical layer (the logic-flow sign-off, the per-page
design discipline, the house rules for figure-vs-commentary rhythm) and outputs
HTML in a fixed brand. This skill owns the Typst/Touying layer: which theme,
which layout, which gadget, and how to compile. When a deck is for an external
brand or must be HTML, use slide-writing. When it is a PDF research talk,
lecture, or briefing, use this skill.
When to use
- A research talk, conference presentation, seminar, or lecture as a PDF deck.
- A project briefing or internal report that should read as deliberate slides.
- Any deck where Touying's
#pauseanimations, math, CeTZ diagrams, or Typst's typesetting are worth more than a browser deck.
When NOT to use
- A brand-locked or investor-facing deck — use
slide-writing(HTML, brand). - A one-page handout or status update — write Markdown.
- An in-paper figure — use Typst directly, or
paper-writer+figure-taste. - A real manuscript with results — use
paper-writer.
The zoo at a glance
Everything lives under skills/slide-writer/zoo/. Compile gallery.typ to see
the whole catalogue rendered (typst compile gallery.typ, or
--input theme=dark to preview any theme).
| Axis | Count | Where | Examples |
|---|---|---|---|
| Color themes | 5 | zoo/themes/ | academic, dark, minimal, vibrant, brand |
| Layouts (slide-body composers) | 9 | zoo/layouts.typ | spread, twocol, threecol, hero, band, cards, punch |
| Gadgets (content components) | ~25 | zoo/gadgets.typ | rail_pull, callout, figbox, stat_row, spec_list, theorem, data_table, conclusion_grid, codebox, toc, pacing |
| CeTZ diagrams (optional) | 4 | zoo/gadgets_cetz.typ | tensor, automaton-state, edge, flowbox |
| Pin annotations (optional) | 3 | zoo/gadgets_pin.typ | pin, highlight, note |
| Touying primitives | — | re-exported by zoo/lib.typ | title-slide, focus-slide, #pause |
Palettes (pure color data) live in zoo/palettes/; each theme maps its palette
onto Touying's config-colors slots. The single import surface is zoo/lib.typ.
Workflow
Borrow the logical discipline from slide-writing (agree the outline before
drawing), then enrich it with the Typst technical layer. Do not reorder — the
sequence is the point.
Phase 0 — Load context
- Read any
docs/discussion/*-brainstorm-ideas-log.mdfor the talk's why. - Pull figures the deck will reuse from
$KB/.figures/, the paper'sfigs/, or a prior talk — do not redraw a figure the author already drew. - If the talk presents a manuscript, read
articles/<paper>/main.typso the deck's claims match the paper's.
Phase 1 — Logic flow (sign-off gate)
Capture topic, audience, key claim in three lines. Propose a section outline of 5–8 sections (12 is the ceiling), one line each:
§N · <section name> — <main claim, 1 sentence> — <figure idea, ≤8 words>
Show the outline and wait for sign-off. A deck whose outline is wrong is wrong on every page; do not touch Typst until the user approves.
Phase 2 — Pick the theme (before any slide)
Choose one theme up front and commit. The decision is audience + room:
| Situation | Theme |
|---|---|
| Conference talk, default, projector-safe | academic |
| Dim room, projector glare | dark |
| Lecture notes printed as slides, handout | minimal |
| Teaching, outreach, back-row energy | vibrant |
| Your lab/product has a house color | brand (pass build(rgb("#…"))) |
Theme-hopping mid-deck reads as inconsistent. Pick once.
Phase 3 — Compose slides from the zoo (one at a time)
For each section in the approved outline, pick a layout/gadget by the slide's
job — the router is references/layout-patterns.md. Write the slide, then show
the user (compiled page or markdown form) before moving on.
Phase 4 — Assemble and verify
- Scaffold a self-contained deck (copies the zoo next to the
.typ):python3 skills/slide-writer/scripts/scaffold.py <target> --name <deck> --theme <theme> - Paste the approved slides into
<deck>.typ. - Compile and walk it:
typst compile <deck>.typ # the compile IS the lint- Every
==heading is a slide; every=is a section divider. - Check: titles carry one italic accent, no slide overflows, every figure is
cited in the rail, the outline (
#toc()) lists the real sections, and no text sits below ~11 pt.
- Every
Phase 5 — Figure-taste pass
Hand any figure-heavy slide to the figure-taste skill (line weight, color
discipline, text size, chartjunk). Slides are the harshest viewing context for a
figure; a figure that survives figure-taste survives a projector.
The preamble (copy once per deck)
#import "zoo/lib.typ": *
#let pal = palettes.academic
#show: themes.academic.with(config-info(
title: [Deck Title], subtitle: [one-line],
author: [Name], date: datetime.today(), institution: [Org],
))
#let (rail_pull, callout, codebox, quote_pull, figbox, portrait, clip_image,
stat, stat_row, spec_list, theorem, definition, lemma, example, proof_box,
badge, tag, time_badge, data_table, conclusion_grid, key_links, toc,
pacing, kicker, progress_dots) = gadgets(pal)
#let (spread, twocol, threecol, hero, band, cards, card, punch,
centered_figure) = layouts(pal)
#title-slide()
== Outline
#toc() // deck-register section list; #outline() is a paper TOC
The two #let lines destructure the gadget/layout factories bound to pal, so
every gadget already knows the active theme's colors. To switch theme, change
palettes.academic → palettes.dark and themes.academic → themes.dark in
those three spots — nothing else moves. Full router + copyable snippets in
references/layout-patterns.md; palette vocabulary in
references/style-tokens.md.
Optional: diagrams and pin annotations
CeTZ and pinit are imported per-section (not in the preamble) so a text-only deck pays no extra-package cost:
#import "zoo/gadgets_cetz.typ": make as make-cetz
#import "@preview/cetz:0.4.2": canvas
#let (tensor, automaton-state, edge, flowbox) = make-cetz(pal)
House rules
- One figure per slide. A second figure means two slides conflated.
- One accent for emphasis. Numerals and
rail_pulluseaccent_deep; do not repaint gadgets by hand — readpal.Xso a theme switch repaints all. - Tabular numbers in mono.
data_tablevalue columns andtime_badgeset it themselves; big display numerals (stat,punch) stay in the theme sans. - Nothing below ~11 pt. Gadget captions and labels bottom out at 10–11 pt by design; if content only fits smaller, the slide holds two slides' worth.
- Pass plain values to gadgets (
[13], not[*13*]): touying show-rulesstrongas an alert and would repaint your bold in theme primary. Gadgets bold and colour their own numerals. - Captions describe how to read the figure, not what it is.
- Use the source's own figures. Pull from
figs/, README, prior slides. Redrawing an author's figure as inline SVG produces a worse copy. - Pick the theme up front. The chrome (header, footer, progress bar) is part of the deck's identity.
==is a slide,=is a section. Don't nest slide content under the wrong heading level.- Recompile the gallery when you add a gadget or layout — it is the visual regression test for the zoo.
Common mistakes
| Mistake | Fix |
|---|---|
| Started composing slides before outline sign-off | Stop. Return to Phase 1. |
| Hardcoded a hex color in a slide | Read pal.X instead, so theme switches propagate. |
Called a gadget as G.figbox(...) | Typst needs the destructure form (figbox(...)) or (G.figbox)(...). Use the preamble's #let destructure. |
| Mixed two themes in one deck | Pick one; the chrome must stay consistent. |
Used // inside markup [...] | // starts a line comment and eats the closing ]. Drop it or use a raw block. |
Wrapped a gadget value in *...* | Touying repaints strong in theme primary (alert). Pass plain content; the gadget bolds. |
Typed a CLI string (--input, <name>) in prose | Markup turns -- into – and eats <name> as a label. Put literal strings in backticks / #raw. |
| Inline-SVG'd a figure that exists in the source | Stop. Embed the source SVG/PDF instead. |
| Added CeTZ/pinit to the preamble of a text deck | Import them per-section; the preamble stays dependency-light. |
| Compile fails on a missing font | The palettes target DejaVu / Noto / New Computer Modern — stock on TeX Live and most Linux installs (Typst itself bundles only NCM, Libertinus, and DejaVu Sans Mono). Confirm with typst fonts before switching families. |
Integrations
- Logical workflow + brand decks:
slide-writing(HTML) is the sibling; this skill borrows its sign-off discipline. - Figures: reuse figures from
paper-writermanuscripts and the project KB; runfigure-tasteon figure-heavy slides (Phase 5). - Brainstorming: a talk often follows a
/brainstorm-ideassession — read its log for the deck's motivation and key claim. - Citations: slides rarely need a bibliography page; if they do, point
\bibliography/#bibliographyat$KB/.knowledge/references.bib.
What's in the bundle
| Path | Purpose |
|---|---|
gallery.typ | Visual index of the whole zoo; compile to browse. --input theme=<name> rethemes. |
zoo/lib.typ | Single import surface: palettes, themes, gadget/layout factories, touying slide primitives. |
zoo/palettes/ | Five pure-data color modules (+ brand.typ's build(primary) generator). |
zoo/themes/ | Five thin metropolis overlays mapping palettes → touying config-colors. |
zoo/gadgets.typ | ~24 palette-aware content components (callouts, stats, theory, structure, chrome). |
zoo/layouts.typ | Nine slide-body composers (spread, twocol, hero, cards, …). |
zoo/gadgets_cetz.typ | Optional CeTZ diagram helpers (tensor, automaton, flowbox). |
zoo/gadgets_pin.typ | Optional pinit annotation helpers (pin, highlight, note). |
references/layout-patterns.md | When-to-use router + copyable snippets. |
references/style-tokens.md | Palette vocabulary, touying slot mapping, per-theme values. |
scripts/scaffold.py | Scaffolds a self-contained deck (copies the zoo next to <name>.typ). |
Extending the zoo
- Add a gadget to
zoo/gadgets.typinsidemake(pal)— return it as a"snake_case": (args) => …entry so it destructures cleanly. - Add its swatch to
gallery.typunder the matching section. - Recompile
gallery.typ; if it renders, the gadget ships. - Document it in
references/layout-patterns.md.
For a new theme, see "Adding a new theme" in references/style-tokens.md.