MolCrafts Zensical Theme
Shared Zensical theme extension for MolCrafts documentation sites.
Install
pip install molcrafts-zensical-theme
Consuming sites should pin the theme in the dependency group that builds their docs so builds stay reproducible:
[dependency-groups]
docs = [
"zensical>=0.0.45",
"molcrafts-zensical-theme>=0.2.3",
]
For theme development, install the checkout in editable mode instead
(pip install -e .).
The distribution includes the MolCrafts C++ handler for mkdocstrings; a
second Python package is not required. Rendering C++ API documentation still
requires the doxygen executable to be available on PATH.
Use
Add the theme to a Zensical project:
[project]
site_name = "MolCrafts Project"
site_url = "https://docs.molcrafts.org/example/"
[project.theme]
name = "molcrafts"
[project.extra.molcrafts]
product = "molpy"
accent = "#0284c7"
accent_soft = "rgba(2, 132, 199, 0.14)"
All three values are optional. product tags the page
(html[data-molcrafts-product="…"]) so site or theme CSS can target one
product. accent sets the product accent (links, hovers, hero eyebrows);
accent_soft is its translucent companion and, when omitted, is derived from
accent via color-mix. Sites that set none of these fall back to the brand
forest/sand accent. The theme ships no per-product color map — each product
declares its own accent in zensical.toml.
The theme defaults to Zensical's modern variant, MolCrafts brand colors from
moko.svg, Inter text, JetBrains Mono code, light/dark palettes, navigation
tabs, section indexes, instant navigation, code-copy controls, search
highlighting and suggestions, and TOC following. Consuming sites should not
re-list these features/palette in their own zensical.toml — the theme
already supplies them, and an inline list only risks drifting from the defaults.
For a normal documentation site, setting name = "molcrafts" is the complete
visual setup: typography, both color modes, component colors, and navigation
behavior are owned by the theme. Product accent settings and the home-page
components below are optional customization, not required theme tokens.
Product extra.css — iron law
Product docs must not re-skin the theme. Palette, hero, manual sections, workflow list, feature matrix, doc-map, tile-grid, link-list, figures, and light/dark schemes live only in this package.
Allowed in product extra.css |
Forbidden |
|---|---|
| Markup unique to that product (e.g. MolPy pipeline strip, product GLB viewer) | Restyling .molcrafts-* components |
Tiny product wordmark / hero wash under html[data-molcrafts-product="…"] |
Re-declaring [data-md-color-scheme] palettes |
| One-off figure sizing for a product page | Copying theme CSS into the product repo |
Accent colours belong in zensical.toml ([project.extra.molcrafts]), not in
product CSS. Prefer promoting a second product's shared layout into a theme
modifier (--cards, --flip, …) over duplicating rules in two extra.css
files. Molpack's ~15-line extra.css is the size model.
Web Component fences (MolVis + MolPlot) — one model
MolVis and MolPlot use the same ownership split so docs sites only depend on this theme (+ zensical):
| Layer | Owner | What you install |
|---|---|---|
| Build-time fence (Markdown → HTML) | this theme | pip install molcrafts-zensical-theme |
| Run-time Web Component | npm package on CDN (or staged node_modules) |
nothing in Python |
extra_javascript = [
# 3D viewer Web Components
{ path = "https://cdn.jsdelivr.net/npm/@molcrafts/molvis-stage@latest/dist/viewer.js", type = "module" },
# 2D sketch engine (when docs embed sketch demos)
{ path = "https://cdn.jsdelivr.net/npm/@molcrafts/molvis-sketch@latest/dist/index.js", type = "module" },
{ path = "https://cdn.jsdelivr.net/npm/@molcrafts/molplot@latest/dist/elements.js", type = "module" },
]
[project.markdown_extensions.pymdownx.superfences]
custom_fences = [
{ name = "mermaid", class = "mermaid" },
{ name = "molvis", class = "molvis", format = "molcrafts_zensical_theme.formatters.molvis_fence" },
{ name = "molvis-gallery", class = "molvis-gallery", format = "molcrafts_zensical_theme.formatters.molvis_gallery_fence" },
{ name = "molplot", class = "molplot", format = "molcrafts_zensical_theme.formatters.molplot_fence", validator = "molcrafts_zensical_theme.formatters.molplot_validator" },
]
MolVis: format="xyz" etc.; gallery accepts src, npts,
rotation-speed. MolPlot: fence body is a Vega-Lite spec (YAML or JSON);
header options preset / theme / width / aspect (default 4:3).
Optional top-level annotations: (molplot extension: scaleBar / arrow) is
passed through to the browser; @molcrafts/molplot expands it into ordinary
Vega-Lite rule/text layers so marks pan/zoom with the chart.
In docs the theme caps chart width (~36rem) and @molcrafts/molplot scales
type with container width so paper-preset fonts stay readable on screen.
Local staging (optional): formatters copy each package dist/ into
docs/assets/ when a source is found (env override → node_modules → monorepo):
| Package | Entry | Staged as | Extra monorepo probe |
|---|---|---|---|
@molcrafts/molvis-stage |
viewer.js |
docs/assets/molvis-stage/ |
— |
@molcrafts/molvis-sketch |
index.js |
docs/assets/molvis-sketch/ |
— |
@molcrafts/molplot |
elements.js |
docs/assets/molplot/ |
../molplot/core/dist |
Treat docs/assets/molplot/ as generated (gitignore in the consumer).
Staging skips *.d.ts, *.map, and *.test.js. Overrides:
MOLVIS_STAGE_DIR, MOLVIS_SKETCH_DIR, MOLPLOT_ELEMENTS_DIR,
MOLCRAFTS_DOCS_ASSET_DIR.
The paper-charting Python package (molcrafts-molplot) does not ship a
Markdown fence — docs sites must use this theme.
Figure cards (MolVis / MolPlot embeds)
One framed card holds the canvas and a journal-style caption underneath.
Put the viewer/chart first, a Figure N. label in the chin, and an id for
cross-references (no product chip):
<figure id="fig-water" class="molcrafts-figure" markdown>
<div class="molcrafts-figure__body">
<molvis-viewer format="xyz" …>…</molvis-viewer>
</div>
**Figure 1.** Water molecule (ball-and-stick). Math works here:
$\varepsilon'(\omega)$.
</figure>
In prose, link with Markdown: [Figure 1](#fig-water).
Why markdown is on <figure>, not <figcaption>: md_in_html does not
re-parse nested <figcaption> content. Put the caption as a trailing Markdown
paragraph inside a markdown-enabled <figure> so arithmatex turns $…$ into
.arithmatex spans MathJax can typeset.
Math (arithmatex + MathJax)
The theme enables navigation.instant, so MathJax must re-typeset after every
client-side page swap. The theme injects the MathJax config (arithmatex
processHtmlClass) and a document$ re-typeset hook automatically. Sites
only need the library itself:
extra_javascript = [
"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js",
]
[project.markdown_extensions.pymdownx]
arithmatex = { generic = true }
Load the MathJax CDN after other extra_javascript entries (or at least
after any script that might set window.MathJax). No separate config file is
required unless you override main.html.
C++ API reference
Enable the bundled handler in the consuming project's zensical.toml:
[project.plugins.mkdocstrings]
default_handler = "cpp"
[project.plugins.mkdocstrings.handlers.cpp]
input = ["include"]
file_patterns = ["*.h", "*.hpp", "*.cpp"]
build_dir = ".cache/mkdocstrings-cpp"
[project.plugins.mkdocstrings.handlers.cpp.options]
show_root_heading = true
members_order = "source"
separate_signature = true
Then use normal mkdocstrings directives in Markdown:
::: my_namespace::MyClass
options:
members_order: source
Home page
The theme ships a manual-style landing layout that a stock Zensical site does not have. It has two parts: a hero driven by page front-matter, and a set of manual-home components you compose in Markdown/HTML in the page body.
Hero (front-matter)
Set a hero mapping in the home page's front-matter; the theme's main.html
renders it above the content. Every field is optional except that a hero only
renders when the hero key is present. The eyebrow above the title defaults to
"Manual" and can be changed with hero.kicker.
---
title: molpack
hide: [navigation, toc]
hero:
kicker: Manual
title: molpack # defaults to site_name if omitted
description: One or two sentences of positioning.
actions: # buttons; style "primary" fills, else outline
- { label: Get started, href: getting_started/, style: primary }
- { label: Guide, href: concepts/ }
install: # right-hand card with copyable tabs
label: Install
methods:
- { label: pip, command: pip install molpack }
- { label: uv, command: uv add molpack }
- { label: source, command: pip install -e . }
badges: # badge row under the install card
- img: https://img.shields.io/pypi/v/molpack
href: https://pypi.org/project/molpack/
alt: PyPI version
---
For a single install command, the old shorthand still works:
hero:
install:
command: pip install molpack
Manual-home components (body)
Wrap the body in .molcrafts-manual-home and compose these building blocks (all
are plain HTML with markdown where inner Markdown is wanted):
| Class | Purpose |
|---|---|
molcrafts-manual-section |
A titled row; pair with molcrafts-manual-section__header + molcrafts-manual-eyebrow |
molcrafts-manual-index |
Numbered "find the right page" entry list (<a><span>01</span><strong>…</strong><em>…</em></a>) |
molcrafts-manual-grid |
Responsive card grid; add --cols-2 or --cols-3 (see templates below) |
molcrafts-manual-list |
Vertical row list of label/description pairs (lighter than manual-index) |
molcrafts-workflow-list |
Side-labelled <article>s, each with a molcrafts-workflow-list__meta tag and a code block |
molcrafts-feature-matrix |
Two-column <dl> of capability <dt>/<dd> pairs |
molcrafts-doc-map |
Grid of <section><h3>…</h3><p>…</p></section> linking to nav areas |
molcrafts-sr-only |
Visually-hidden <h1> so the page still has a heading for a11y/search |
See examples/docs/index.md for a complete, copyable example, and the
molpy / molpack docs/index.md for production use.
Section templates
A section is built from two orthogonal, opt-in choices so a sub-manual picks a layout instead of relying on grid auto-placement. Pick a frame (how the titled block splits its label from its content) and drop a content template (how the items inside are arranged) into it.
Frames — modifiers on molcrafts-manual-section:
| Modifier | Layout |
|---|---|
| (none) | Two columns: a sticky label column beside the content |
--compact |
Two columns with a static label; a trailing paragraph stacks under the label while the content (e.g. a code block) spans the second column |
--stack |
Single column: eyebrow + title on top, content full width below — use to host wide content or a three-column grid |
Content templates — drop one into a frame's body (or straight into
molcrafts-manual-home):
| Template | Arrangement |
|---|---|
molcrafts-manual-grid molcrafts-manual-grid--cols-2 |
Two-column card grid → one column on narrow screens |
molcrafts-manual-grid molcrafts-manual-grid--cols-3 |
Three-column card grid → two, then one |
molcrafts-manual-list |
Vertical list of rows |
molcrafts-manual-index |
Numbered entry list |
Each card / row is an <a> (link, with accent hover) or a <div>, holding a
<strong> label and an <em> or <p> description. A three-column grid needs
the room a --stack frame gives it:
<section class="molcrafts-manual-section molcrafts-manual-section--stack" markdown>
<div class="molcrafts-manual-section__header" markdown>
<span class="molcrafts-manual-eyebrow">Capabilities</span>
## What molpy gives you
</div>
<div class="molcrafts-manual-grid molcrafts-manual-grid--cols-3">
<a href="build/"><strong>Build</strong><em>Assemble systems from parts.</em></a>
<a href="type/"><strong>Type</strong><em>Assign force-field parameters.</em></a>
<a href="export/"><strong>Export</strong><em>Write LAMMPS, GROMACS, PDB.</em></a>
</div>
</section>
Local Example
zensical build -f examples/zensical.toml
zensical serve -f examples/zensical.toml
The usage surface is Zensical-native: configure sites with zensical.toml.
Zensical 0.0.45 still discovers packaged themes through the historical
mkdocs.themes entry point and reads theme-package defaults from
mkdocs_theme.yml; this package uses those hooks only for Zensical theme
discovery, not for mkdocs.yml configuration.
Package layout
The mkdocs.themes entry point resolves to molcrafts_zensical_theme.templates,
and Zensical takes the theme directory to be that module's directory — then
copies every non-template file it finds there into the built site. So the theme
directory holds theme files only; package code (formatters) lives one level up
in molcrafts_zensical_theme, the same split as material.templates upstream.
tests/test_theme_package.py guards it.
src/molcrafts_zensical_theme/
├── __init__.py
├── formatters.py # importable as molcrafts_zensical_theme.formatters
└── templates/ # ← theme directory
├── mkdocs_theme.yml
├── main.html
├── partials/
└── assets/
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file molcrafts_zensical_theme-0.2.8.tar.gz.
File metadata
- Download URL: molcrafts_zensical_theme-0.2.8.tar.gz
- Upload date:
- Size: 65.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54fa67c039f9077f50be0ceb6f9d9fd738643cd6c6a8415ebc3feda1fc9509b3
|
|
| MD5 |
704f2459927d4eabf563dad2ada18566
|
|
| BLAKE2b-256 |
77c30fde568a1ffb114edc0c19100f506de064f525cd0d3d6d23a19c229a2bdc
|
Provenance
The following attestation bundles were made for molcrafts_zensical_theme-0.2.8.tar.gz:
Publisher:
release.yml on MolCrafts/molcrafts-zensical-theme
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
molcrafts_zensical_theme-0.2.8.tar.gz -
Subject digest:
54fa67c039f9077f50be0ceb6f9d9fd738643cd6c6a8415ebc3feda1fc9509b3 - Sigstore transparency entry: 2349262757
- Sigstore integration time:
-
Permalink:
MolCrafts/molcrafts-zensical-theme@2cc58aa78899559f3ded5af5d60df1a23b52ad5a -
Branch / Tag:
refs/tags/v0.2.8 - Owner: https://github.com/MolCrafts
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2cc58aa78899559f3ded5af5d60df1a23b52ad5a -
Trigger Event:
push
-
Statement type:
File details
Details for the file molcrafts_zensical_theme-0.2.8-py3-none-any.whl.
File metadata
- Download URL: molcrafts_zensical_theme-0.2.8-py3-none-any.whl
- Upload date:
- Size: 57.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a65ef7f4e88e0b842246963111588484cddc01f713c6ea17c7d58cb56c183de6
|
|
| MD5 |
cd30f82cbc4424116c5276457287b2f8
|
|
| BLAKE2b-256 |
b80399c0df523988610ac212a8c97604cff82167750a31cf09dcb5fd19472262
|
Provenance
The following attestation bundles were made for molcrafts_zensical_theme-0.2.8-py3-none-any.whl:
Publisher:
release.yml on MolCrafts/molcrafts-zensical-theme
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
molcrafts_zensical_theme-0.2.8-py3-none-any.whl -
Subject digest:
a65ef7f4e88e0b842246963111588484cddc01f713c6ea17c7d58cb56c183de6 - Sigstore transparency entry: 2349262865
- Sigstore integration time:
-
Permalink:
MolCrafts/molcrafts-zensical-theme@2cc58aa78899559f3ded5af5d60df1a23b52ad5a -
Branch / Tag:
refs/tags/v0.2.8 - Owner: https://github.com/MolCrafts
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2cc58aa78899559f3ded5af5d60df1a23b52ad5a -
Trigger Event:
push
-
Statement type: