This is the guide to Markdown Converter — a web app that takes a single markdown document and renders it as a styled HTML page. The markdown is generated by an AI instance following a defined spec; the HTML is rendered by the application using a user-selected theme. The markdown stays portable. Presentation lives entirely in the application layer.
What It Is
v0.2 — reconciled to implementation. Live at md-converter.designs-os.com.
A single-page web application. You upload one markdown file. It picks a theme, applies it, and renders the file as themed HTML — tabs, callouts, stat cards, mermaid diagrams, the lot. You can tweak the theme from a sidebar in real time, save the result as a self-contained HTML file, and round-trip the styling as a portable JSON config.
It is intentionally narrow. One markdown in, one HTML out. Multi-document projects, inline editing, image hosting — none of these are part of the tool. The portable content is always somebody else's input; the converter only owns the presentation layer.
The markdown is theme-agnostic. The same file renders correctly under any of the bundled themes — or any future theme that conforms to the canonical class skeleton.
Core Principle
Instruct structure, not semantics. The AI is told only how to organise its output. Visual treatment, color, layout, and typography are decisions made by the application — never by the AI, never embedded in the markdown.
The result: markdown that works in any standard markdown viewer (because it carries no styling), and HTML that can be re-themed at any time (because the theme is bound at render time, not write time).
User Flow
- Prompt an AI instance that has the themed-markdown skill loaded (see AI Skill).
- The AI generates a single markdown document conforming to the spec.
- Upload the markdown to the converter web app.
- Select a theme — or import a saved config.
- The app renders the markdown as themed HTML.
- Adjust styling via the sidebar, export the result, or save the config.
Markdown Spec
The full syntax the AI emits and the converter parses. This is the contract between the AI's output and the converter's input.
Frontmatter
Every document begins with a YAML frontmatter block:
---
title: Document Title
tags: [tag1, tag2]
date: YYYY-MM-DD
project: Project Name
purpose: Brief description
---
title and tags are required; tags may be empty. date, project, and purpose are optional and render as footer metadata in the HTML output.
Document Structure
| Markdown | Role | Rendered As |
|---|---|---|
# Title | Document title (once, at top) | Captured as docTitle; falls back to frontmatter.title |
## Section | Major section | Sidebar tab; H2 text becomes both the tab label and the panel's H1 |
### Heading | Subsection | <h3> inside tab content |
H4–H6 are not supported. Content between an H2 and the next H2 belongs to that H2's tab — no explicit delimiters needed. Any content between the H1 and the first H2 is dropped. A document with no H2 headings gets a single default tab containing all content.
Standard Markdown
Paragraphs, inline emphasis (**bold**, *italic*, ~~strike~~, `code`), links, images, GFM pipe tables, unordered and ordered lists (including nesting), and fenced code blocks all render through markdown-it's default rules.
Images take URLs only — no relative paths. Blockquotes (other than callouts), footnotes, and raw HTML are not supported.
Color Class System
Four semantic classes are defined: class1, class2, class3, class4. The AI chooses which class fits each piece of content; the converter applies the theme's color for each class. Classes are used by callouts, stat cards, mermaid nodes, and linear diagram steps.
Callouts
> [!class1]
> Callout content
Replace class1 with any of the four classes.
Stat Cards
Stat cards are grouped in a stats fenced block:
```stats
:::class1
value: 87%
label: User satisfaction
description: Up 12% from last quarter
:::class2
value: 1.2M
label: Active users
```
Per-card fields: value and label are required; description is optional.
Mermaid & Linear Diagrams
Standard mermaid syntax in a fenced block. Nodes may be assigned classes with :::classN:
```mermaid
graph LR
A[Start]:::class1 --> B[Middle]:::class2 --> C[End]:::class3
```
The renderer injects a classDef preamble so :::class1–:::class4 bind to the active theme's colors automatically.
For simpler linear flows or timelines, the linear fence uses -> to separate steps, each optionally tagged with a class:
```linear
Step 1 :::class1 -> Step 2 :::class2 -> Step 3 :::class3
```
Task Lists
Standard GFM task list syntax — - [ ] for incomplete, - [x] for complete. The renderer styles them as a dedicated .task-list with custom checkbox markers.
Themes
A theme is a structured set of design tokens (colors, fonts) plus a CSS stylesheet that targets the canonical class skeleton. Themes are fully decoupled — the same markdown renders correctly under any of them.
Five themes ship in the bundle:
| Theme | Mode | Character |
|---|---|---|
| Editorial | light | Magazine / literary aesthetic. DM Serif Display + Source Serif 4. |
| Bauhaus | light | Swiss-grid technical. Archivo + IBM Plex. |
| Terminal | dark | Cyberpunk monospace. Syne + JetBrains Mono. |
| Atelier | dark | Luxe architectural. Cormorant Garamond + Manrope. |
| Dossier | dark | Quiet-technical-warm. Fraunces italic numerals + DM Sans. |
Each theme provides twelve canonical color tokens (bg, bg-2, bg-3, text, text-soft, rule, rule-soft, accent, class1–class4) and three typography tokens (font-display, font-body, font-mono). Tokens are applied as CSS custom properties on :root — sidebar overrides take precedence.
Style Sidebar
The right-edge slide-in panel toggled by a floating Style button (Esc closes). Changes apply immediately via CSS variable updates — no re-render needed.
Controls
- Theme — five swatches (background + accent dot) with active state styling.
- Colors — one row per canonical color token. Each row pairs a native color picker with a hex text input that stay in sync, plus a reset arrow that appears only when the value is overridden.
- Typography — three font fields (
font-display,font-body,font-mono). Each is a grouped<select>over a curated face list (every face is preloaded by some bundled theme), plus a Custom… option that reveals a free-text input for any CSSfont-familystring. - Top actions — Upload markdown / Export HTML / Export config / Import config / Download Skill for AI.
- Footer action — Reset overrides.
Picking a theme clears overrides (fresh start). Reset overrides clears them without changing theme.
Live Preview
Color and font edits update the rendered document immediately via inline :root style mutations. Mermaid diagrams re-render on theme change and on class1–class4 / bg / text changes, so their inline SVGs follow the palette.
AI Skill
A Claude-format skill file (themed-markdown.skill.md) is bundled into the app and downloadable from the sidebar via Download Skill for AI. It carries a name + description frontmatter so it can be loaded into any skill-aware AI tool (Claude Code, Claude API agents, etc.) and auto-invoked when the user asks for output in this format. Non-skill-aware tools can still load it as a system prompt or persistent instruction.
The skill body is short (~700 tokens including the example) to minimise context overhead. It contains the syntax rules, when-to-use triggers, output contract, and one minimal example — no styling instructions.
When the AI follows the skill, its output:
- Begins with valid YAML frontmatter
- Uses only the constructs defined in the spec above
- Applies
class1–class4semantically (the AI picks which class fits each piece of content) - Does not include styling values, theme references, or visual instructions
Config Export & Import
The active theme + color overrides + font overrides export as a single JSON file:
{
"version": 1,
"theme": "editorial",
"colorOverrides": { ... },
"fontOverrides": { ... }
}
Export: downloads as md-converter-<theme>.config.json.
Import: file picker; validated against the schema — unknown keys filtered, non-string values dropped, unknown theme rejected.
HTML Export
Exported HTML is fully self-contained:
- Inlined base CSS + active theme CSS + a
:root { ... }override rule reflecting whatever sidebar tweaks were active at export time - Google Fonts referenced via
<link>(not inlined as base64) - Mermaid diagrams pulled from the live DOM as already-rendered inline SVG — no
mermaid.jsruntime in the export - Vanilla tab-switch JS for click-to-switch behaviour — no SvelteKit hydration needed
- No external CSS or JS dependencies beyond Google Fonts
Open the exported file directly in any browser. It carries every visual decision the user made at export time.
Persistence
Active theme + color overrides + font overrides persist to localStorage under md-converter-config-v1, using the same JSON shape as config export. Restore runs once on mount; save fires on every state change. The whole interaction is wrapped in try/catch so a full or disabled localStorage degrades silently.
Deferred Features
Out of scope for v0.2 but tracked for future versions:
- Drag-and-drop markdown upload UI
- Inline markdown editing within the app
- Multi-document projects
- URL-based config sharing
- Print stylesheet variants
- Accessibility audit (WCAG AA contrast checking on custom configs)
- Image captions (italic line following an image →
<figcaption>) - Size sliders in the sidebar (themes currently hard-code font sizes)
- Per-theme construct opt-out (themes declaring “I don't render mermaid well, skip it”)
- Validation of AI output against the spec — current behaviour is best-effort render
Part of the Emergence Project. Built by the Design/OS shell team.
May 26th 2026