Skip to content
Reference
On this page
  1. Stable names
  2. Markdown rules
  3. Component structure
  4. Slot contract
  5. Right-to-left and math
  6. Posts and archives
Page actions

Public API

The public API is documented here; changes are listed in CHANGELOG.md. Anything not listed (internal includes, Sass partial paths, private --mt-p-* primitives, HTML details that no rule describes) can change in any release.

Stable names

Area Stable names
Settings every key under modootoday: listed in Configuration
Design tokens semantic and component custom properties --mt-* (not the primitives --mt-p-*); the generated tokens.json mirrors them
Markdown rules the patterns in RULES.md and their output classes mt-*; the opt-out class mt-flat-list (no gap between list items below it)
Layouts default, doc, post, archive, twin, llms, llms-full
Includes you may override head-custom.html, footer-custom.html; modootoday/lang-switch.html and modootoday/brand/logo.html (takes size) can be included from your footer; override modootoday/brand/logo.html to draw your own logo
Includes you provide _includes/sections/<name>.html, rendered at the end of a section or the hero by visual: <name> (see Customize)
Includes you may call modootoday/archive.html with by and lang; modootoday/brand/icon.html with name (globe, sun, moon, search, menu, copy, check, external, prev, next, chevron-right, chevron-down, note, tip, important, warning, caution, edit, rss, tag, folder, brand), optional size (px, default 18), label (makes it role="img" with that name; otherwise aria-hidden) and class. Output: svg.mt-icon.mt-icon-<name> in currentColor; directional icons add .mt-icon-flip (mirrored in RTL)
Includes modootoday/t.html (key=, optional n= / name=) prints a theme label for the page language
Data files _data/i18n/<lang>.yml keys (optional overrides of the built-in catalogs), _data/nav/<name>.yml, _data/components.yml
Checker the modootoday-check options, exit code 0 (no problems) and 1 (problems or bad usage)

Markdown rules

md-components v1 is the name of the Markdown rules standard in RULES.md; it is not a CSS prefix. Output classes use mt-*.

Component structure

This is the markup you can target from your own CSS today. Classes and attributes in this table are part of the public API; elements inside them that the table does not name (wrappers, generated ids, the order of child elements) are not. The slot contract names the Markdown parts each component consumes.

Component Root Parts you may style State and variants
Page shell body.mt-body a.mt-skip, header.mt-header > .mt-header-inner (.mt-site-title, nav.mt-nav, .mt-search, details.mt-lang.mt-menu (summary globe button, ul of a[lang][hreflang], current one aria-current), .mt-theme-toggle), main.mt-main, footer.mt-footer > .mt-footer-inner html[data-theme=light\|dark] (fixed scheme, or set by the toggle)
Doc page article.mt-doc .mt-doc-layout > .mt-doc-main and .mt-doc-aside (holds nav.mt-toc), nav.mt-toc-mobile, nav.mt-breadcrumb, .mt-page-meta, nav.mt-pagination —
Doc sidebar aside.mt-doc-nav > nav.mt-sidebar (from 64rem); details.mt-sidebar-mobile (below) .mt-sidebar-group, .mt-sidebar-title, the ul of links; the current link has aria-current=page .mt-doc-layout.mt-has-sidebar; [open] on the mobile menu
Page actions details.mt-menu.mt-page-actions summary, the ul of button[data-mt-act=copy\|ai] (hidden until JS runs) and the View as Markdown a[type="text/markdown"] [open]
Hero section.mt-hero the h1, lead p.mt-hero-lead (the first p right after the h1), link-only p (CTA buttons; first link is primary) .mt-hero-checks (front matter hero: {checks: true}: the first ul is a row of ✓ marks in --mt-ok)
Section section.mt-section the h2 and its content [data-section] = name; [data-c] and .mt-c-<c> = component; .mt-cols-<n>; .mt-cta (on the section, or on a [data-mt-result] element inside it when one is present)
Section decor .mt-has-decor on section.mt-hero or section.mt-section (front matter decor: <include>) .mt-section-decor[aria-hidden=true], the last child, holding _includes/sections/<include>.html; placed in the top end corner, no pointer events —
Scroll reveal .mt-reveal on section.mt-hero or section.mt-section (front matter reveal: true) — CSS only: fades in on scroll inside @supports (animation-timeline: view()) and prefers-reduced-motion: no-preference; shown as is otherwise
Full-width band .mt-bleed on section.mt-hero or section.mt-section (front matter bleed: true), .mt-bleed-wide (bleed: wide) — --mt-bleed-bg sets the band colour; inside a sidebar or table-of-contents layout the band stays in the main column; bleed sheet
Illustration figure.mt-illustration[role=img][aria-label] (your own include) .mt-illustration-tag badge in the top start corner; its text belongs in the aria-label too, because the children of role=img are not read —
List styles ul.mt-chips; li > strong.mt-item-title + span.mt-item-sep (with modootoday.lists) the li > a chips (44px tall, → after the text); the title and the : separator —
Prose (no sections:) div.mt-prose the rendered body —
Card grid section.mt-section ul > li, its leading strong is the title .mt-cols-2, .mt-cols-3, .mt-cols-4, .mt-badge-bottom (c: features)
Tabs section.mt-c-tabs[data-tabs] [role=tablist], [role=tab], [role=tabpanel] (built by JS; without JS the h3 + code blocks stay) [aria-selected]
Accordion section.mt-c-accordion h3 > button[aria-expanded], the panel after it [aria-expanded=true\|false]
Steps / Timeline section.mt-c-steps, section.mt-c-timeline ol > li or h3 items —
File tree section.mt-c-filetree ul[aria-label], nested ul (items holding one are folders) —
Details / FAQ section.mt-c-details, section.mt-c-faq details.mt-details, summary > h3, the content after it [open]
Parameter table section.mt-c-params th[scope=col], .mt-param-required —
Link cards section.mt-c-linkcards ul > li > a (the whole card is the link target) —
Quote figure.mt-quote blockquote, figcaption —
Gallery section.mt-c-gallery a.mt-gallery-thumb, a.mt-lightbox, .mt-lightbox-close :target on the open lightbox
Pricing .mt-plans .mt-plan, its h3, link-only p.mt-actions .mt-plan-recommended with .mt-plan-flag
Subscribe section.mt-c-subscribe form.mt-subscribe (when an action is set), label, input[type=email], button —
Split section.mt-c-split (with .mt-split-start, .mt-split-5-7) .mt-section-in > .mt-section-body (the h2 and text) + .mt-section-visual (the visual: include). hero: {c: split} puts section.mt-hero in the same wrappers, with the h1, lead, check row and actions in .mt-section-body. visual: code puts the first code block in div.mt-section-visual.mt-split-code; chrome: terminal adds .mt-split-terminal and div.mt-split-bar (aria-hidden). —
Inline extras div.mt-code, span.mt-progress, div.mt-embed .mt-code-title, progress, iframe —
Loading (optional sheet) .mt-spinner, .mt-topbar, .mt-skeleton .mt-skeleton-text, -card, -image, -avatar, -row; .mt-ratio-16x9, -4x3, -1x1 [aria-busy=true], [role=status]
Banner div.mt-banner its p and link; a.mt-back-to-top —
Alert blockquote.mt-callout[role=note] p.mt-callout-title, the body .mt-callout-<type>, [data-variant] = note, tip, important, warning, caution
Badge span.mt-badge the symbol (aria-hidden), the label .mt-badge-<status>, .mt-badge-tag, [data-variant]
Keyboard keys kbd.mt-kbd kbd per key —
Figure figure.mt-figure img, figcaption —
Post header header.mt-post-header h1.mt-post-title, .mt-post-deck, .mt-byline (.mt-byline-authors > .mt-post-author, .mt-byline-dates > time), figure.mt-post-cover, nav.mt-series, p.mt-post-meta (tag badges) [data-part] = header, deck, byline, authors, dates, cover, terms
Post footer article.mt-doc .mt-share button, nav.mt-post-nav, section.mt-related, .mt-news-correction, .mt-news-sources [data-part] = share, post-nav, related, sources
Post card article.mt-card-post .mt-card-post-cover, .mt-card-post-meta, .mt-card-post-title, .mt-card-post-excerpt .mt-card-post-featured, [data-kind=news], .mt-post-list[data-variant=list\|grid\|magazine]
News front div.mt-news-top .mt-news-lead, .mt-news-secondary, section.mt-news-latest, section.mt-news-section [data-category], .mt-badge[data-variant=breaking\|live]
Search div.mt-search[role=search] the input, .mt-search-results —

Slot contract

A slot is a named part of a section’s Markdown. Slot names are stable under the policy above, and declaring them never changes the generated markup. modootoday-check counts each slot in every section whose c: has a slots: entry in _data/components.yml, and fails when a count is outside the declared range.

Slot What it counts in the section (after its ## heading) Renders as
lead Plain paragraphs before the first list, ###, code block or quote p
items List items ul > li or ol > li (cards, steps)
panels ### headings tab, accordion or step panels
actions Link-only lines CTA buttons (c: cta)
code Fenced code blocks pre (tab content)
figures Lines that start with an image figure.mt-figure

Each slot takes required: true (same as min: 1), min and max (whole numbers, min not greater than max). For a component that has two valid shapes, slots: can be a list of alternative forms; a section passes when it satisfies any one of them. parts: lists the selectors from the component structure table that the component promises to keep; when the site has an api.md with that table, every part must appear in it. When Nokogiri is available (it is under github-pages), every part must also match inside a section of that component in the built HTML of the pages that use it; parts that component scripts add at runtime (role=, aria-*) are checked after the scripts run by the docs site QA.

features: {params: {cols: {allowed: [2, 3, 4]}, badge: {allowed: [bottom]}}, slots: {items: {min: 1}}, parts: [ul > li, .mt-cols-2, .mt-cols-3, .mt-cols-4, .mt-badge-bottom]}
tabs: {i18n: [tabs.label], slots: {panels: {min: 2}, code: {min: 2}}}
cta: {slots: {actions: {required: true}}, parts: [.mt-cta]}
accordion: {slots: {panels: {min: 1}}}
steps: {slots: [{items: {min: 1}}, {panels: {min: 1}}], parts: [section.mt-c-steps, ol > li]}

A component entry takes only params, i18n, slots and parts, and a slot rule only required, min and max. Any other key, an unknown slot name, a min above max or a list of fewer than two forms is an error, reported once per registry. Components without slots: are not counted, and a single-map slots: behaves exactly as before.

Right-to-left and math

  • Pages in Arabic, Persian, Hebrew, Urdu and other RTL languages get dir="rtl" from lang; set direction: rtl or ltr in front matter (or direction: in _data/i18n/<lang>.yml) to override. Components use logical properties and mirror; code stays left-to-right.
  • The theme bundles no math or diagram renderer; see Math and diagrams.

Posts and archives

Posts use the post layout: a date, author and tag line, the body, then a footer that links each category and tag to its archive section. Set the archive pages in _config.yml:

modootoday:
  archive: {tags: /tags/, categories: /categories/}

Then add one page per taxonomy, for example tags.md:

---
title: Tags
layout: archive
archive: tags        # or categories
---

The page shows its own body, an index of terms with post counts, and one section per term (id="tags-<slug>", newest post first). To place an archive anywhere else, call the include modootoday/archive.html from a layout or include, with by set to tags or categories and an optional lang. Archive styles live in modootoday-blog.css: the archive and post layouts load it, and any other page that calls the include needs blog_css: true in its front matter.

  • A post’s language is its lang (or site.lang). An archive lists only posts in the page’s language; archive_lang: all (or lang="all" on the include) lists every post. Footer links of a post whose lang differs from site.lang point at /<lang>/tags/, so add an archive page under each language directory.
  • Labels come from archive.tags, archive.categories, archive.posts and archive.empty in _data/i18n/<lang>.yml, with English fallbacks.
  • Limits: classic GitHub Pages runs no custom plugin, so there is one page per taxonomy with an anchor per term, not one page per term. Posts get no Markdown twin; agents find them through the archive links. Jekyll puts the folder names above _posts/ into categories, so keep posts in the top-level _posts/ and set lang: in front matter.

Edit this page