Guidance for AI coding agents working in the Mat3ra documentation
repository. Read this alongside WRITING-STYLE.md
and README.md, which remain the canonical references for
prose style and formatting respectively. For running structured quality
reviews, see REVIEW.md.
- Source for docs.mat3ra.com, built with MkDocs using the Material theme.
- English Markdown lives in
lang/en/docs/. Other languages underlang/<code>/docs/are regenerated bytranslate.py— do not edit them by hand. - Navigation is wired in
mkdocs.yml. Any page that is added, renamed, or moved must be updated there in the same change. - Some tutorial pages have a sibling
.jsonmetadata file used by the voiceover/video tooling described inINTERNAL.md. When renaming the.md, rename the.jsonto match. - Images live under
images/<section>/and are tracked with Git LFS. Prefer.webp, keep each file below 1 MB, and use natural-language hyphen-case names.
The documentation is split into four MkDocs sites, each with its own config file and URL prefix:
| Site | Config | URL path | Landing page |
|---|---|---|---|
| Top-level (legacy) | mkdocs.yml |
/ |
index.md |
| Tutorials / Guide | mkdocs-guide.yml |
/guide/ |
index-guide.md |
| Concepts/Reference | mkdocs-concepts.yml |
/reference/ |
index-concepts.md |
| Developer Docs | mkdocs-dev.yml |
/dev/ |
index-dev.md |
Key points:
- The top-level site (
mkdocs.yml) contains the full navigation and acts as a hub. Itsindex.mdhas clickable cards linking to the three sub-sites. - Each sub-site config inherits common settings (theme, CSS, JS) but
defines its own
nav:,site_name, andsite_url. - Each sub-site has a
← All Docsentry at the top of itsnav:that links back to the root (/). This is a hardcoded absolute path — Jinja2 macros do not render insidenav:definitions.
Links between sub-sites use Jinja2 macro variables defined in extra:
of each config:
extra:
guide_url: https://docs.mat3ra.com/guide
reference_url: https://docs.mat3ra.com/reference
dev_url: https://docs.mat3ra.com/dev| Link target is… | Use this form |
|---|---|
| In the same sub-site | Relative path: [text](../path/to/page.md) |
| In a different sub-site | Macro link: [text]({{ reference_url }}/path/to/page/) |
Never hardcode https://docs.mat3ra.com/guide/… in Markdown — always
use the macro variable so serve-all.sh can rewrite it for local
development.
Each sub-site config has an exclude_docs: block listing directories
and files that belong to other sites. Some directories are split between
sites at the page level (e.g., jobs/overview.md → Reference,
jobs/actions/ → Guide). When linking, check the target page's
exclude_docs status in the config of the site the source page belongs
to. If the target is excluded, use a macro link.
Some pages contain raw Jinja2 code examples (e.g., templating
tutorials with {{ input.RESTART_MODE }}). The macros plugin would
try to resolve these as variables, causing errors or empty output.
The fix:
- Leave
render_macros: true(or omit it — the default istrue). - Wrap raw Jinja code blocks in
{% raw %}…{% endraw %}.
Critical rule: never set render_macros: false on a page that
contains cross-site macro links ({{ guide_url }}, etc.). Setting it
to false prevents ALL macros from resolving, leaving them as literal
text in the HTML and creating broken links. The only pages that may
use render_macros: false are those with no cross-site macro links at
all (e.g., benchmarks/2018-11-12-comparison.md).
After building, run the post-build link checker:
.venv/bin/python scripts/links/check-links.pyThis scans every <a href> in the built site/ directory and verifies
that the target file exists. Exit code 1 means broken links were found.
Helper scripts in scripts/links/:
check-links.py— post-build internal link checker (the main tool).find-cross-site-links.py— detect which pages contain cross-site refs.fix-broken-cross-links.py— repair broken inter-site links.rewrite-cross-site-links.py— convert hardcoded URLs to macros.urls-to-macros.py— bulk converthttps://docs.mat3ra.com/guide/…to{{ guide_url }}/….
Use scripts/serve-all.sh to build and serve all four sites:
# Serve on default port 8000
./scripts/serve-all.sh
# Serve on a specific port
PORT=8888 ./scripts/serve-all.sh
# Build only (no server)
./scripts/serve-all.sh --buildThe script:
- Creates temporary local config overrides (
.local-mkdocs*.yml) that rewrite cross-site URLs tolocalhost. - Builds all four sites into
site/,site/guide/,site/reference/,site/dev/. - Fixes sub-site homepages (copies from
index-<site>/index.htmlto the root of each sub-site). - Starts
python -m http.serveron the chosen port. - Cleans up temp configs on exit.
Do not use mkdocs serve for multi-site work — it only serves one
site at a time.
When adding a new CSS or JS file, plugin, or theme setting, it must be added to all four config files:
mkdocs.ymlmkdocs-guide.ymlmkdocs-concepts.ymlmkdocs-dev.yml
The top-level index.md uses HTML cards inside a <div class="section-cards">.
Styles are in lang/en/docs/extra/css/general.css.
Important CSS notes:
- Do not use the class name
.grid— MkDocs Material reserves it for its own grid system and will override the styles. - MkDocs wraps inline
<a>tags inside<p>elements. The CSS targets.section-cards > p(margin: 0, display: flex) to make<p>a transparent grid item, then stylesa.grid-cardwith flexbox for equal-height cards. - Cards use
display: flex; flex-direction: column; flex: 1to stretch to equal height within the CSS Grid row.
WRITING-STYLE.md is authoritative. Key rules:
- Simple, dry, concise. Drop adorning adjectives ("complete list of all the many different items" → "the list of items").
- Third person or passive voice — never "you" or "your". Use "the user" or "this can be accessed".
- Present tense over future tense.
- Avoid these words: Simply, Clearly, Obviously, In fact, Furthermore, Moreover, Complete, In particular, Really, Distinct, Various, Automatically, Finally.
- Prefer "click the button" over "click on the button".
- Don't start a sentence with a short interjection like "To" — use "In order to" instead. The same applies to "By", "From", etc.
- Introduce acronyms on first mention per page ("Density Functional Theory (DFT)"). Do not put acronyms in headers.
- For external concepts, link to Wikipedia or the upstream source rather than re-explaining them.
- Follow Object-Oriented Design: encapsulate each topic in its own section, abstract shared concepts to the parent page, and let specific pages inherit context from the section overview.
- Exactly one H1 (
#) per page, on the first line. Use H2/H3/H4 for the rest. - For long pages, enumerate sections and subsections:
## 1. Section,### 1.1. Subsection. - Leave one blank line between paragraphs and after every heading. Leave 2–3 blank lines when returning from a deeper level to a shallower one.
- No trailing whitespace; one blank line at the end of file.
- Use relative paths for all internal links and image references.
- For images, use Markdown syntax
; reserve HTML for clickable maps,giffferGIFs, and YouTube embeds. - Use admonitions for callouts:
!!!tip "Title",!!!info "Title",!!!warning "Title". - Inline UI references:
**Run**for buttons,*Workflow*for tab or section names,`MATERIAL`for code identifiers or commands.
The MatterSim tutorial
(lang/en/docs/tutorials/ml/run-mlff-python-workflows-mattersim.md) is
the current reference for tutorial style. Apply the same patterns to
other tutorial pages.
Third-level subheadings name an action the user performs. Use the imperative form, not the gerund.
| Avoid | Prefer |
|---|---|
### 1.1. Importing a workflow |
### 1.1. Import a workflow |
### 4.1. Confirming GPU access |
### 4.1. Confirm GPU access |
### 4.2. Example Results |
### 4.2. Example results |
Top-level ## N. titles may stay in gerund form when they label an
approach ("Using a bank workflow", "Creating a new workflow"). Avoid
awkward connectors such as "By creating ...".
Open every section with a prose sentence that orients the reader, then introduce a list only if it adds value. For short procedural steps, prefer prose with "First, … Then, …" transitions over a bullet list.
Avoid:
### 1.1. Import a bank workflow
- Navigate to the *Workflows Bank* page from the left sidebar.
- Search for `MatterSim` and click **Copy** ...Prefer:
### 1.1. Import a bank workflow
First, navigate to the *Workflows Bank* page from the left sidebar.
Then, search for `MatterSim` and click **Copy** ...- Flatten nested bullet lists to a single level. If a sub-list needs context, lift it out and introduce it with a prose sentence.
- Keep images, code blocks, and follow-on paragraphs flush-left. Do not nest them inside list items; break the surrounding list into prose instead.
- Every image has both alt text and a title attribute.
- Use
<wbr/>to allow soft word-breaks in long slash-separated terms (e.g.flavor/<wbr/>template).
- Make the smallest diff that satisfies the request. Don't touch files the user didn't ask about.
- Don't edit translated pages under non-
enlanguages unless asked — they are regenerated bytranslate.py. - Never stage or commit unless the user explicitly asks.
- When renaming a tutorial page, update in the same change:
- the
.mdfile, - the sibling
.jsonmetadata file (if present), - the entry in
mkdocs.yml.
- the
- New images go under
images/<section>/as.webp, hyphen-case, under 1 MB. - Use
tmp/for throwaway test scripts (Playwright, etc.). This directory is git-ignored.
The MkDocs Material theme shows repository stars, forks, and latest
tag in the header via its built-in source component. This relies on
client-side JavaScript that fetches from api.github.com. When
rate-limited (common on localhost), the stats silently disappear. This
is expected behavior — they work in production. Do not add custom
JavaScript workarounds for this; the native mechanism is sufficient.
- One H1; sub-headers in sentence case; no acronyms in headers.
- No list starts directly under a heading.
- Lists are flat; images and code blocks are flush-left.
- Third person / passive voice; no "you" or "your".
- None of the forbidden words from
WRITING-STYLE.md. - Acronyms are introduced on first use.
- Same-site links and image paths use relative paths.
- Cross-site links use
{{ guide_url }},{{ reference_url }}, or{{ dev_url }}macros — not hardcoded URLs. - Pages with raw Jinja code use
{% raw %}blocks — notrender_macros: false— if they also contain cross-site macros. -
mkdocs.ymlis updated if pages were added, renamed, or moved. - Changes to CSS/JS/plugins are reflected in all four config files.
- Post-build link check passes:
.venv/bin/python scripts/links/check-links.py. - Only the files the user asked about were modified.