Skip to main content

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
[project.extra.molcrafts]
enable_molplot = true   # theme loads staged local assets/molplot/elements.js, then the npm CDN

extra_javascript = [
  # 3D viewer Web Components
  { path = "https://cdn.jsdelivr.net/npm/@molcrafts/molvis-stage-viewer@0.2.0/dist/main.js", type = "module" },
  # 2D sketch custom element (when docs embed sketch demos)
  { path = "https://cdn.jsdelivr.net/npm/@molcrafts/molvis-sketch-viewer@0.2.0/dist/main.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 plain Vega-Lite spec (YAML or JSON); header options preset / theme / width / aspect / interactive (default aspect 16:10). Use native VL layer + mark: text|rule for labels — there is no molplot annotation extension. 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 main.js docs/assets/molvis-stage-viewer/ ../molvis/stage-viewer/dist
@molcrafts/molvis-sketch-viewer main.js docs/assets/molvis-sketch-viewer/ ../molvis/sketch-viewer/dist
@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_VIEWER_DIR, MOLVIS_SKETCH_VIEWER_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

molcrafts_zensical_theme-0.3.0.tar.gz (68.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

molcrafts_zensical_theme-0.3.0-py3-none-any.whl (60.4 kB view details)

Uploaded Python 3

File details

Details for the file molcrafts_zensical_theme-0.3.0.tar.gz.

File metadata

  • Download URL: molcrafts_zensical_theme-0.3.0.tar.gz
  • Upload date:
  • Size: 68.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for molcrafts_zensical_theme-0.3.0.tar.gz
Algorithm Hash digest
SHA256 743c2bd6e5bc5387454aceccc40a38b876df70b9b6f37cbefa17cbd34962ee04
MD5 98a8aa98a841b2cb265979da2cd8c2f3
BLAKE2b-256 2b4b0af914ac49e06dca0b81c3d1d5aeae0f04c1036d756c4a2eaeeca8768ed1

See more details on using hashes here.

Provenance

The following attestation bundles were made for molcrafts_zensical_theme-0.3.0.tar.gz:

Publisher: release.yml on MolCrafts/molcrafts-zensical-theme

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file molcrafts_zensical_theme-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for molcrafts_zensical_theme-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fe484e2e4b8f634b2a46d2ff3433b30f0dae5f8c4327606289414b2cef5a7e8d
MD5 ef2fc56250ca8b0cc732f81174738579
BLAKE2b-256 6c17ae54e4a8d979b9503a72e767d0a123ebf421d3010706c1146d706e4d15f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for molcrafts_zensical_theme-0.3.0-py3-none-any.whl:

Publisher: release.yml on MolCrafts/molcrafts-zensical-theme

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.9

2 files

0.2.8

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page