Render a presentation-brief.md (v4.0) into a self-contained HTML slide presentation with speaker notes toggle, keyboard navigation, themed styling, and Mermaid diagram support. After rendering, supports an interactive refinement loop where users can adjust individual slides — text fixes are applied directly to HTML, structural changes trigger a targeted re-render. Use this skill whenever the user mentions "HTML slides", "HTML presentation", "browser presentation", "render slides as HTML", "self-contained slides", "slide deck in browser", "web slides", "present in browser", or wants a presentation without PowerPoint. Also use when the user asks to "open slides in browser", "export slides as HTML", "refine slides", "adjust slide", "fix slide", or says "no PowerPoint". Works with any presentation-brief.md generated by story-to-slides.
From cogni-visualnpx claudepluginhub cogni-work/insight-wave --plugin cogni-visualThis skill is limited to using the following tools:
references/01-layout-renderers.mdreferences/02-slide-navigation.mdreferences/03-speaker-notes.mdscripts/generate-html-slides.pyProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Transform a presentation-brief.md (v4.0) into a stunning, self-contained HTML slide deck
that runs in any browser. Themed styling, keyboard navigation, smooth transitions,
speaker notes panel, Mermaid diagram rendering, touch swipe support, and print mode —
all in a single .html file.
| Parameter | Default | Description |
|---|---|---|
brief_path | auto-discovered | Path to presentation-brief.md |
theme | from brief frontmatter | Path to theme.md (or omit for pick-theme) |
design_variables | derived from theme | Pre-computed design-variables.json path |
output_path | {brief_dir}/{slug}-slides.html | HTML output path |
transition | fade | Slide transition: fade, slide, none |
aspect_ratio | 16:9 | Slide aspect ratio: 16:9, 4:3 |
language | from brief frontmatter | en or de |
max_refinements | 3 | Max refinement rounds after rendering (0 = skip refinement) |
brief_path provided, use it directly**/presentation-brief.md (max 3 levels deep)type: presentation-brief (must match)version: "4.0" (content-only schema)theme, theme_path, language, customer, provider, arc_type, governing_thoughtTheme resolution (3-stage, same as enrich-report):
design_variables parameter provided → use directly, skip to Phase 1theme parameter provided → read that theme.mdtheme_path from brief frontmattercogni-workspace:pick-theme via Skill toolParse the presentation-brief.md body into structured slide data. The brief uses ## Slide N: {headline} sections with fenced YAML blocks.
For each slide section, extract:
number — slide numberheadline — the assertion headline from the H2 headinglayout — the Layout field valuefields — all layout-specific fields as a nested object (preserving structure)speaker_notes — the Speaker-Notes field (multi-line string, preserve verbatim)bottom_banner — Bottom-Banner field if presentdiagram_mermaid — the Diagram field content if it contains Mermaid syntaxcitations — extracted <sup>[N](url)</sup> patternsWrite the parsed data to {brief_dir}/cogni-visual/slide-data.json:
{
"metadata": {
"title": "...",
"subtitle": "...",
"customer": "...",
"provider": "...",
"language": "de",
"arc_type": "why-change",
"generated": "2026-02-09",
"governing_thought": "..."
},
"slides": [
{
"number": 1,
"headline": "Assertion headline",
"layout": "title-slide",
"fields": {
"Title": "...",
"Subtitle": "...",
"Metadata": "..."
},
"speaker_notes": null,
"bottom_banner": null,
"diagram_mermaid": null,
"citations": []
}
]
}
Parsing rules:
--- (horizontal rule) in the brief|) — preserve the full textDiagram: field as multi-line stringsLabel: field inside each box — but the Python script handles localization, so just pass the text contentText: key or a plain stringIf design_variables path was not provided:
design-variables.json with this structure:{
"theme_name": "smarter-service",
"colors": {
"primary": "#111111",
"secondary": "#333333",
"accent": "#C8E62E",
"accent_muted": "#A8C424",
"accent_dark": "#8BA31E",
"background": "#FAFAF8",
"surface": "#F2F2EE",
"surface2": "#E8E8E4",
"surface_dark": "#111111",
"border": "#E0E0DC",
"text": "#111111",
"text_light": "#FFFFFF",
"text_muted": "#6B7280"
},
"status": {
"success": "#2E7D32",
"warning": "#E5A100",
"danger": "#D32F2F",
"info": "#1565C0"
},
"fonts": {
"headers": "'Bricolage Grotesque', -apple-system, sans-serif",
"body": "'Outfit', -apple-system, sans-serif",
"mono": "'JetBrains Mono', monospace"
},
"google_fonts_import": "@import url('https://fonts.googleapis.com/css2?family=...');",
"radius": "12px",
"shadows": {
"sm": "0 1px 3px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.06)",
"md": "0 4px 16px rgba(0,0,0,0.06), 0 1px 4px rgba(0,0,0,0.04)",
"lg": "0 12px 40px rgba(0,0,0,0.1), 0 4px 12px rgba(0,0,0,0.05)",
"xl": "0 24px 64px rgba(0,0,0,0.14), 0 8px 20px rgba(0,0,0,0.06)"
}
}
Extract all values from the theme.md. For any color not explicitly stated in the theme, derive sensible defaults:
accent_muted — accent color darkened ~15%accent_dark — accent color darkened ~30%surface2 — slightly darker than surfacesurface_dark — use primary or darkest colorborder — light gray matching surface toneThe schema matches ${CLAUDE_PLUGIN_ROOT}/../enrich-report/schemas/design-variables.schema.json.
Write to {brief_dir}/cogni-visual/design-variables.json.
Run the Python generator script:
python3 "${CLAUDE_PLUGIN_ROOT}/skills/render-html-slides/scripts/generate-html-slides.py" \
--slide-data "{brief_dir}/cogni-visual/slide-data.json" \
--design-variables "{brief_dir}/cogni-visual/design-variables.json" \
--output "{output_path}" \
--transition "{transition}" \
--aspect-ratio "{aspect_ratio}" \
--language "{language}"
The script outputs JSON: {"status": "ok", "path": "...", "slides": N, "size_kb": N.N} or {"error": "..."}.
If error, read the error message and attempt to fix the input data. Common issues:
After successful generation, verify:
<section class="slide"> elements in the HTML matches the slide count in the brief<template class="slide-notes-data"> block<sup>[N](url)</sup> patterns from the brief appear as <a class="citation"> elements in the HTML<pre class="mermaid"> blocks:root CSS with design variable tokensRead the generated HTML and spot-check these. If any fail, diagnose and fix.
open "{output_path}"
After the user has seen the slides in the browser, offer an interactive refinement loop.
Skip this phase entirely if max_refinements is 0.
Ask via AskUserQuestion:
"The slides are open in your browser. Would you like to refine anything? Describe what to change (e.g. 'Slide 3 headline too long', 'Slide 7 should use four-quadrants layout'), or say 'done' to finish."
Exit the loop if the user says "done", "looks good", "no", or gives an empty response.
Parse the user's feedback and classify each change request:
| Category | Examples | Channel |
|---|---|---|
| text-fix | Typo, number correction, headline rewording, bullet text | HTML edit |
| style-fix | Font size, spacing, color on a specific element | HTML edit |
| speaker-notes | Add/change/remove speaker notes content | HTML edit |
| layout-swap | Change from two-columns to four-quadrants | Re-render |
| content-restructure | Split slide, merge slides, reorder slides | Re-render |
| add-slide | Insert a new slide | Re-render |
| remove-slide | Delete a slide | Re-render |
| theme-adjust | Global color/font change across all slides | Re-render |
| data-change | Mermaid diagram content, chart data | Re-render |
Decision rule: If the change affects only the text or inline styles of an existing slide element, use the HTML edit channel. If it changes layout structure, slide count, slide order, or global styling, use the re-render channel.
For HTML-edit changes:
<section class="slide" data-slide="N"> block<template class="slide-notes-data"> blockFor re-render changes:
{brief_dir}/cogni-visual/slide-data.jsonFor mixed changes in the same round: Apply re-render changes FIRST (they produce a fresh HTML file), then apply HTML-edit changes to the fresh file. This ordering prevents HTML edits from being overwritten.
open "{output_path}"
max_refinements: return to Step 6.1max_refinements: inform the user the refinement cap is reachedNavigation: Arrow keys, Space, Page Up/Down, Home/End. Click right = next, left = prev. Touch swipe on mobile.
Speaker Notes: Press S to toggle the notes panel at the bottom. Notes show "WHAT YOU SAY" coaching tags and "WHAT YOU NEED TO KNOW" context, fully parsed from the brief's speaker notes format.
Transitions: Smooth fade (default), slide, or instant. Configurable via transition parameter.
Theming: Full design token injection from theme.md via CSS custom properties. Every color, font, shadow, and radius is theme-driven.
Mermaid Diagrams: Automatically detected and rendered via Mermaid.js CDN for process-flow, layered-architecture, and gantt-chart layouts.
Print Mode: Ctrl+P renders all slides sequentially with speaker notes visible and navigation controls hidden. Each slide gets its own page.
Responsive: Aspect ratio is preserved via CSS aspect-ratio + min() constraints. Graceful degradation on mobile with stacked layouts.
Self-contained: Single HTML file. All CSS inline. All JS inline. Only external dependency is Mermaid.js CDN (conditional, only included when diagrams are present).
Refinement Loop: After viewing slides, give feedback on specific slides in natural language. Text and style fixes are applied directly to the HTML (instant). Structural changes (layout swaps, slide additions) trigger a targeted re-render via the Python script. Max 3 rounds by default.