| name | htmlify-v2 |
| description | Convert any content (markdown, specs, plans, findings) into a polished, self-contained static HTML document with a modern light/muted design. V2 standalone. |
Please deep think / ultrathink as this is a complex task.
htmlify-v2
Static HTML document generator — takes any content the user points to (markdown files, notes, specs, plans, conversation context) and produces a polished, self-contained HTML file. Zero dependencies, opens directly in a browser, ready to share or print to PDF.
User input:
$ARGUMENTS
Expected usage patterns:
```bash
/htmlify <source> # HTMLify a file or path
/htmlify <source> --output path/to/out.html # Specify output path
/htmlify # HTMLify from conversation context
/htmlify --dark # Use dark variant
```
Where `<source>` can be:
- A file path (markdown, text, any readable file)
- A directory (concatenates relevant files)
- Omitted — uses the current conversation context or the user's description
Purpose
Produce beautiful, zero-dependency static HTML documents from raw content. The output should look like a polished report you'd share with stakeholders — not a raw markdown render. Think Notion page or Linear changelog — clean, readable, professional.
Flow
1) Parse Arguments
- Determine the source content (file path, directory, or conversation context)
- Determine the output path (default: same directory as source, with
.html extension; for context-based, use ./scratch/ or current directory)
- Determine theme (default: light;
--dark for dark variant)
2) Load & Analyse Source Content
- Read the source content fully
- Identify the document structure:
- Title and subtitle
- Sections and their hierarchy
- Tables, lists, code blocks
- Diagrams (mermaid candidates)
- Key findings, recommendations, callouts
- Metrics or summary data
- Determine which components best represent each content element
3) Generate HTML
Rules:
- Use semantic HTML throughout — real HTML elements, NOT markdown rendered at runtime
- First line of the output file MUST be:
<!-- Generated by htmlify-v2 -->
- All CSS is inlined in a
<style> block — single self-contained file
- Select appropriate accent colours from the palette to visually distinguish sections
- Use callout variants to match tone (see palette below)
- Use tables for structured comparisons — don't force everything into cards
- Add anchor navigation bar if the document has 3+ sections
- Include mermaid diagrams where content describes flows, architectures, or relationships
- Add mermaid.js CDN script ONLY if mermaid diagrams are present
- Preserve the substance and detail of the source — don't summarise or truncate
4) Write Output
- Write the HTML file to the determined output path
- Confirm the output path and file size to the user
- Suggest
open <path> to preview
Built-in Design System
The skill carries its own CSS. No external template files needed.
Design Principles
- Light and airy — generous whitespace, muted backgrounds, subtle borders
- Typography-first — Inter/system font stack, clear hierarchy, comfortable reading width
- Muted accents — no saturated primaries; use soft, desaturated tones
- Minimal chrome — content speaks, UI disappears
Colour Palette (Light Mode)
:root {
--bg: #FAFAFA;
--bg-card: #FFFFFF;
--bg-nav: #F5F5F4;
--text: #1C1917;
--text-muted: #78716C;
--text-subtle: #A8A29E;
--border: #E7E5E4;
--border-hover: #D6D3D1;
--accent-blue: #6B9BD2;
--accent-green: #6BA387;
--accent-amber: #C4985A;
--accent-rose: #C47A7A;
--accent-purple: #9B8EC4;
--accent-teal: #5DA3A3;
--info-bg: #EFF6FF; --info-border: #93C5FD;
--success-bg: #F0FDF4; --success-border: #86EFAC;
--warning-bg: #FFFBEB; --warning-border: #FCD34D;
--error-bg: #FEF2F2; --error-border: #FCA5A5;
--insight-bg: #FAF5FF; --insight-border: #C4B5FD;
--neutral-bg: #F5F5F4; --neutral-border: #D6D3D1;
--code-bg: #F5F5F4;
--code-text: #292524;
--radius: 8px;
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2.5rem;
}
Colour Palette (Dark Mode — --dark flag)
:root {
--bg: #1A1A1A;
--bg-card: #242424;
--bg-nav: #1E1E1E;
--text: #E7E5E4;
--text-muted: #A8A29E;
--text-subtle: #78716C;
--border: #333333;
--border-hover: #444444;
--accent-blue: #7DADE2;
--accent-green: #7DB89B;
--accent-amber: #D4A86A;
--accent-rose: #D48A8A;
--accent-purple: #ADA0D4;
--accent-teal: #6DB3B3;
--info-bg: #1E293B; --info-border: #60A5FA;
--success-bg: #14291E; --success-border: #6EE7A0;
--warning-bg: #2D2410; --warning-border: #FBBF24;
--error-bg: #2D1414; --error-border: #F87171;
--insight-bg: #1E1533; --insight-border: #A78BFA;
--neutral-bg: #262626; --neutral-border: #404040;
--code-bg: #2A2A2A;
--code-text: #E7E5E4;
}
Core CSS
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.7;
max-width: 860px;
margin: 0 auto;
padding: var(--space-xl) var(--space-lg);
}
h1 { font-size: 2rem; font-weight: 700; letter-spacing: -0.02em; margin-bottom: var(--space-xs); }
h2 { font-size: 1.35rem; font-weight: 600; letter-spacing: -0.01em; margin-top: var(--space-xl); margin-bottom: var(--space-md); color: var(--text); }
h3 { font-size: 1.1rem; font-weight: 600; margin-top: var(--space-lg); margin-bottom: var(--space-sm); }
.subtitle { color: var(--text-muted); font-size: 0.95rem; margin-bottom: var(--space-xl); }
p { margin-bottom: var(--space-md); }
.nav {
display: flex; flex-wrap: wrap; gap: var(--space-sm);
padding: var(--space-sm) var(--space-md);
background: var(--bg-nav); border-radius: var(--radius);
margin-bottom: var(--space-xl); border: 1px solid var(--border);
}
.nav a {
color: var(--text-muted); text-decoration: none; font-size: 0.85rem;
font-weight: 500; padding: var(--space-xs) var(--space-sm);
border-radius: 4px; transition: all 0.15s;
}
.nav a:hover { color: var(--text); background: var(--border); }
.card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--radius); padding: var(--space-lg);
margin-bottom: var(--space-lg);
}
.card.border-blue { border-left: 3px solid var(--accent-blue); }
.card.border-green { border-left: 3px solid var(--accent-green); }
.card.border-amber { border-left: 3px solid var(--accent-amber); }
.card.border-rose { border-left: 3px solid var(--accent-rose); }
.card.border-purple { border-left: 3px solid var(--accent-purple); }
.card.border-teal { border-left: 3px solid var(--accent-teal); }
.callout {
padding: var(--space-md) var(--space-lg);
border-radius: var(--radius); margin-bottom: var(--space-md);
border-left: 3px solid; font-size: 0.92rem;
}
.callout.info { background: var(--info-bg); border-color: var(--info-border); }
.callout.success { background: var(--success-bg); border-color: var(--success-border); }
.callout.warning { background: var(--warning-bg); border-color: var(--warning-border); }
.callout.error { background: var(--error-bg); border-color: var(--error-border); }
.callout.insight { background: var(--insight-bg); border-color: var(--insight-border); }
.callout.neutral { background: var(--neutral-bg); border-color: var(--neutral-border); }
.badge {
display: inline-block; font-size: 0.75rem; font-weight: 600;
padding: 2px 8px; border-radius: 10px;
background: var(--neutral-bg); color: var(--text-muted);
}
.badge.blue { background: var(--info-bg); color: var(--accent-blue); }
.badge.green { background: var(--success-bg); color: var(--accent-green); }
.badge.amber { background: var(--warning-bg); color: var(--accent-amber); }
.badge.rose { background: var(--error-bg); color: var(--accent-rose); }
.badge.purple { background: var(--insight-bg); color: var(--accent-purple); }
table { width: 100%; border-collapse: collapse; margin-bottom: var(--space-md); font-size: 0.9rem; }
th { text-align: left; font-weight: 600; color: var(--text-muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; padding: var(--space-sm) var(--space-md); border-bottom: 2px solid var(--border); }
td { padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--border); }
tr:last-child td { border-bottom: none; }
code { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 0.85em; background: var(--code-bg); color: var(--code-text); padding: 2px 6px; border-radius: 4px; }
pre { background: var(--code-bg); padding: var(--space-md); border-radius: var(--radius); overflow-x: auto; margin-bottom: var(--space-md); border: 1px solid var(--border); }
pre code { background: none; padding: 0; }
.verdict {
background: var(--bg-card); border: 2px solid var(--accent-green);
border-radius: var(--radius); padding: var(--space-lg);
margin: var(--space-xl) 0; text-align: center;
}
.verdict h3 { margin-top: 0; color: var(--accent-green); }
.flow-step {
display: flex; align-items: flex-start; gap: var(--space-md);
margin-bottom: var(--space-md); padding: var(--space-md);
background: var(--bg-card); border-radius: var(--radius); border: 1px solid var(--border);
}
.flow-step .step-num {
flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
background: var(--accent-blue); color: white; font-weight: 700;
font-size: 0.8rem; display: flex; align-items: center; justify-content: center;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--space-md); }
@media (max-width: 640px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }
.phase-label {
display: inline-block; font-size: 0.75rem; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.08em;
color: var(--text-muted); margin-bottom: var(--space-sm);
}
ul, ol { padding-left: var(--space-lg); margin-bottom: var(--space-md); }
li { margin-bottom: var(--space-xs); }
hr { border: none; border-top: 1px solid var(--border); margin: var(--space-xl) 0; }
.mermaid { margin: var(--space-md) 0; text-align: center; }
@media print {
body { max-width: 100%; padding: 1cm; }
.nav { display: none; }
.card { break-inside: avoid; }
}
Component Catalogue
| Component | Class | When to Use |
|---|
| Card | .card .border-{colour} | Wrap sections; vary border colour per section |
| Callout | .callout .{info|success|warning|error|insight|neutral} | Highlight key points, warnings, tips |
| Badge | .badge .{blue|green|amber|rose|purple} | Status labels, categories, tags |
| Table | <table> | Structured data, comparisons |
| Verdict | .verdict | Key conclusions, final recommendations |
| Flow Step | .flow-step + .step-num | Sequential processes, numbered steps |
| Grid | .grid-2 / .grid-3 | Side-by-side layouts |
| Phase Label | .phase-label | Phase markers in phased work |
| Nav | .nav | Anchor navigation for 3+ sections |
| Code | <pre><code> | Code blocks |
| Mermaid | .mermaid | Architecture diagrams, flows |
Colour Selection Guide
Rotate border colours across sections for visual distinction:
Section 1 → border-blue
Section 2 → border-teal
Section 3 → border-purple
Section 4 → border-amber
Section 5 → border-green
Section 6 → border-rose
Don't use the same colour for adjacent cards.
Example Output Structure
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document Title</title>
<style>
</style>
</head>
<body>
<h1>Document Title</h1>
<p class="subtitle">Context · Date</p>
<nav class="nav">
<a href="#overview">Overview</a>
<a href="#findings">Findings</a>
<a href="#recommendations">Recommendations</a>
</nav>
<div id="overview" class="card border-blue">
<h2>Overview</h2>
<p>Content goes here...</p>
</div>
<div class="callout info">
<strong>Note:</strong> Important context the reader should know.
</div>
<div id="findings" class="card border-teal">
<h2>Key Findings</h2>
<table>
<tr><th>Finding</th><th>Impact</th><th>Status</th></tr>
<tr><td>Finding 1</td><td>High</td><td><span class="badge rose">Critical</span></td></tr>
<tr><td>Finding 2</td><td>Medium</td><td><span class="badge amber">Review</span></td></tr>
</table>
</div>
<div id="recommendations" class="card border-purple">
<h2>Recommendations</h2>
<div class="flow-step">
<div class="step-num">1</div>
<div><strong>First step</strong> — do this thing first.</div>
</div>
<div class="flow-step">
<div class="step-num">2</div>
<div><strong>Second step</strong> — then do this.</div>
</div>
</div>
<div class="verdict">
<h3>Verdict</h3>
<p>Summary conclusion here.</p>
</div>
</body>
</html>
Quality Standards
- Output must be visually polished — intentionally designed, not auto-generated
- Content hierarchy must be clear — use card borders, headings, and spacing
- Don't over-componentise — plain paragraphs inside cards are fine
- Tables should be used for tabular data; don't convert tables to cards
- Mermaid diagrams must be syntactically correct
- HTML must render correctly when opened directly in a browser (file:// protocol)
- Preserve the substance and detail of the source — don't summarise or truncate
Anti-Patterns
- Rendering markdown at runtime with a JS library
- Using the same card border colour for every section
- Converting every paragraph into a callout
- Losing content detail during conversion
- Adding build tools, npm, or any dependencies
- Generating broken mermaid syntax
- Forgetting the comment on line 1