Assets guide
A curriculum this size will accumulate hundreds of images. Without a budget and
a layout convention, the repository becomes slow to clone and impossible to
audit. Both are enforced by pnpm content:assets.
Where files go
static/img/<module-directory>/<document-slug>/<name>.<ext>
The path mirrors the document that owns the asset, so deleting a lesson makes its orphaned assets obvious — and the orphan check fails the build until they are removed.
Genuinely shared diagrams live in static/assets/diagrams/. Downloadable files
— sample repositories, cheat sheet PDFs — live in static/assets/downloads/.
Referencing an asset
Docusaurus serves static/ at the site root, and the site is deployed under a
base path. Always use a root-relative path; never ../../static/...:

For a decorative image, or a diagram with a transparent background that should
not get a border, append #plain:

Formats
| Content | Format | Why |
|---|---|---|
| Diagrams, graphs, flowcharts | Mermaid or <GitGraph> | Text, diffable, themable, accessible — always the first choice |
| Diagrams that must be hand-drawn | SVG | Scales, small, editable in a text editor |
| Screenshots of a GUI | WebP, PNG fallback | Lossless where it matters, small |
| Photographs | WebP | Nothing in this curriculum should need one |
| Animations | Not permitted | Use a <Terminal> sequence or a lab instead |
Prefer generated diagrams over drawn ones. A Mermaid diagram is reviewable in a pull request; a PNG is not. Reach for an image file only when the diagram genuinely cannot be expressed as text.
Size budget
| Limit | Value | Enforcement |
|---|---|---|
| Single file | 400 KB | Error |
| Per-module total | 20 MB | Error |
| Screenshot width | 1600 px maximum | Convention |
Before committing a raster image:
# Lossless PNG optimisation
oxipng -o 4 --strip safe image.png
# Or convert to WebP, which is usually 30–50% smaller
cwebp -q 82 image.png -o image.webp
For high-density displays, supply a @2x variant beside the original and let
the browser choose. @2x is the only filename suffix permitted.
Naming
Lower-case kebab-case, describing the content, not the circumstances of capture:
| Good | Bad |
|---|---|
todo-list-editor.png | Screenshot 2026-07-22 at 14.32.11.png |
three-way-merge.svg | diagram2-final-v3.svg |
[email protected] | conflict_markers_2x.PNG |
Alt text
Every image needs alt text, and it is checked.
- Describe what the image shows, not what it is. "Diagram of the merge" is not alt text; "Two branches converging on a merge commit whose parents are the tips of each branch" is.
- Screenshots: describe the state being demonstrated, not the chrome. Nobody needs to know it was a macOS window.
- Decorative images take
alt=""and#plain. An image with no informational content and no empty alt is an accessibility defect.
Licensing
Only commit assets you created, or that are licensed compatibly with CC BY-SA
4.0. Third-party assets require an attribution line in
static/assets/ATTRIBUTION.md recording the source, the author and the licence.
Never commit a screenshot containing a real person's name, a private repository
URL, an email address or a token. Use example.com, octocat and obviously
fictional data.