Show your presentations with charts, diagrams, and code highlighting. Works with most AI coding tools (Claude Code, Codex, Cursor, AMP).
SaferSkills independently audited slide-sage (Agent Skill) and scored it 87/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 3 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 3 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Create data-rich, interactive HTML presentations as single files with charts, diagrams, and code highlighting.
<style> before referencing them in HTML. Never use inline style="..." for properties that repeat across 2+ elements. Read references/css-class-inventory.md for all available classesDetermine what the user wants:
scripts/extract-pptx.py or scripts/extract-pdf.py, then treat extracted JSON as input for Mode AWhen enhancing existing presentations:
Goal: Always confirm key decisions with the user before generating — even when the prompt is detailed.
Always ask these two questions together in a single message, regardless of how much detail the user provides:
Question 1 — Audience & Purpose:
"Who is the audience? (e.g., investors, engineers, students, general)"
Question 2 — Style:
"Any style preference? I have 6 presets: - Arctic Dawn — Cool blues, clean (science/research) - Ember — Warm on dark, high contrast (dashboards/metrics) - Jade Circuit — Green/gold on charcoal (engineering/architecture) - Dusk Palette — Muted purple/pink (creative/design) - Monochrome Pro — Grayscale + accent (executive/formal) - Ocean Deep — Navy, aqua, coral (corporate/professional) - Or tell me your brand colors for a custom theme"
If the user already specified audience and style in their prompt, acknowledge their choices and confirm: "I'll use [audience] targeting with [preset]. Sound good?"
After the always-ask questions, add any of these that apply:
| Missing Info | Question |
|---|---|
| No data provided but topic implies data | "Do you have specific data/metrics, or should I use representative examples?" |
| Ambiguous scope | "Roughly how many slides? (5 for a quick update, 15+ for a deep dive)" |
| Business/corporate context and no brand info | "Any brand colors or logo to incorporate? (Skip if not needed)" |
Never ask about: animation level (detect from audience), library choices (auto-select), file format (auto-detect), presenter mode (default to comment notes).
If the planned presentation has more than 15 slides, present a brief slide outline before generating:
"Here's the planned structure ([N] slides): 1. Title 2. Agenda 3-5. [Section name] ... [N]. Closing
>
Does this look right, or should I adjust?"
For 15 slides or fewer, skip the outline confirmation and proceed directly to Phase 2.
Analyze the user's content to determine what's needed.
Scan the user's message for:
| Signal | Content Type | Action |
|---|---|---|
| Numbers, metrics, KPIs, percentages | Data/Charts | Read references/viz-integration.md |
| "Architecture", "flow", "system design", "pipeline" | Diagrams | Read references/diagram-patterns.md (CSS/HTML preferred, SVG templates, inline SVG) |
| Code snippets, "API", "endpoint", function names | Code slides | Read references/code-highlighting.md |
| Comparative language ("vs", "compared to", "before/after") | Comparison slides | Use comparison templates |
| JSON/CSV data pasted or file referenced | Data parsing | Parse inline or read file |
| .pptx file path | PPT conversion | Run scripts/extract-pptx.py |
| .pdf file path | PDF conversion | Run scripts/extract-pdf.py |
| Images referenced | Image processing | Use scripts/process-images.py if needed |
| Architecture with specific tech (DB, cloud, auth, security) | Icons | Read references/icon-library.md |
Based on content types, decide which CDN libraries to include. Do NOT ask the user — just select:
| Need | Library | CDN |
|---|---|---|
| Bar, line, pie, scatter, radar charts | Chart.js 4.4 | cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js |
| Heatmap, sankey, treemap | ECharts 5.5 | cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js |
| Custom statistical charts | D3.js v7 | cdn.jsdelivr.net/npm/[email protected]/dist/d3.min.js |
| Code syntax highlighting | Prism.js | cdn.jsdelivr.net/npm/[email protected]/prism.min.js |
| Number animations | CountUp.js | cdn.jsdelivr.net/npm/[email protected]/dist/countUp.umd.js |
| Typing effects (title slides) | Typed.js | cdn.jsdelivr.net/npm/[email protected]/dist/typed.umd.js |
| Hand-drawn diagram accents | Rough.js | cdn.jsdelivr.net/npm/[email protected]/bundled/rough.js |
| Generative backgrounds | q5.js | cdn.jsdelivr.net/npm/q5@2/q5.min.js |
| Icons for diagrams/content | Lucide (inline) | Inline SVG paths from templates/icons/lucide-sprite.svg — no CDN needed |
Default: If the presentation has only text, include NO extra libraries. CSS animations suffice.
| Audience Signal | Level |
|---|---|
| "Technical", "engineers", "developers", "code review" | Minimal |
| "Business", "stakeholders", "team update" | Balanced |
| "Pitch", "investors", "conference", "keynote", "wow" | Dramatic |
| No signal | Balanced (default) |
Read references/style-guide.md for the full style system.
Tier 1: Data-Viz Palettes — Always applied. Colorblind-safe chart colors regardless of aesthetic choice.
Tier 2: Named Presets — If user didn't specify a style, choose based on content:
| Content Type | Recommended Preset |
|---|---|
| Scientific, research, data analysis | Arctic Dawn (cool blues, clean) |
| Dashboard, metrics, data-heavy | Ember (warm on dark, high contrast) |
| Engineering, technical architecture | Jade Circuit (green/gold on charcoal) |
| Creative, design, marketing | Dusk Palette (muted purple/pink) |
| Minimal, executive, formal | Monochrome Pro (grayscale + accent) |
| Corporate, professional | Ocean Deep (navy, aqua, coral) |
Tier 3: Custom Theme — If user provides brand colors, generate a custom theme using the theme builder algorithm.
:root from the chosen presetAlways read:
references/html-template.md — Base HTML structure, SlidePresentation classreferences/viewport-system.md — Responsive CSS rulesassets/viewport-base.css — Core CSS to inlinereferences/css-class-inventory.md — Available CSS classes and inline style rulesConditionally read (based on Phase 2 analysis):
references/viz-integration.md — If charts/datareferences/diagram-patterns.md — If architecture/flow diagramsreferences/animation-guide.md — For animation patterns at detected levelreferences/code-highlighting.md — If code snippetsreferences/presenter-mode.md — If user explicitly requests presenter viewBefore generating, plan the slide deck:
Content exceeds limits? Split into multiple slides. Never cram, never scroll.
Structure the HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[Presentation Title]</title>
<link href="[Google Fonts URL]" rel="stylesheet">
<style>
/* viewport-base.css (inlined) */
/* Chosen style preset CSS variables */
/* Animation keyframes for detected level */
/* Code theme CSS (if code slides) */
/* Prism.js theme (if code slides) */
</style>
</head>
<body>
<div class="slides-container">
<div class="slide" id="slide-1">
<div class="slide-content">
<!-- Slide content -->
</div>
<!-- NOTES: Speaker notes here -->
</div>
<!-- More slides -->
</div>
<div class="progress-bar"><div class="progress-fill"></div></div>
<div class="slide-counter"></div>
<!-- CDN libraries (only those needed) -->
<script src="[Chart.js CDN if needed]"></script>
<script src="[Prism.js CDN if needed]"></script>
<script>
// SlidePresentation class (from html-template.md)
// Chart initializations
// Diagram template rendering
// Prism.highlightAll() — MUST call after DOM ready
</script>
</body>
</html>When creating charts, follow these rules:
max-height: min(55vh, 420px)animation: false)Use a CSS-first approach for all diagrams.
Tier 0: CSS/HTML Diagrams (PREFERRED — use for 80% of diagrams)
Styled divs with flexbox/grid, borders, and accent colors. Full theme integration, perfect sizing, zero dependencies. Use the utility classes from viewport-base.css:
.sequence-flow, .seq-participants, .seq-actor, .seq-step, .seq-arrow.arch-stack, .arch-row, .arch-row-group.pyramid, .pyramid-layer.process-flow, .process-step, .process-arrow.card-accent, .card-top-accent with CSS GridSee references/diagram-patterns.md Tier 0 for complete HTML patterns.
Tier 1: SVG Templates — If the diagram matches a common pattern, use a pre-designed SVG template from templates/diagrams/. Available: microservices, data-pipeline, client-server, layered-arch, cicd-pipeline, hub-and-spoke, cloud-three-tier, kubernetes-cluster, event-driven-pubsub, ml-pipeline, c4-context, network-zones, api-gateway-auth, pyramid-roadmap, funnel, nested-scopes, tree-hierarchy. Write only the data object (~200-400 chars)
Tier 2: Inline SVG — Only for fully custom diagrams needing precise geometry (network topologies, custom shapes). Use viewBox + preserveAspectRatio + CSS variables for colors. Never use raw coordinate math for arrows — use CSS borders or SVG <marker> with clean polygon definitions.
For diagram style:
When slides reference specific technologies or infrastructure components, enhance visual recognition with icons from the curated Lucide icon set.
When to use icons:
How to include:
references/icon-library.md for the full icon catalog and path datatemplates/icons/lucide-sprite.svg at the top of <body> (before slides)<use href="#icon-name"> inside inline SVG diagrams<svg class="icon"> elements in HTML slide contentIcon sizing:
width="20" height="20" for standard boxes, width="16" height="16" for small contexts.icon CSS class (1.2em, inherits text color)Rules:
currentColor — they automatically match the presentation themeWhen content involves comparisons (before/after, pros/cons, A vs B):
templates/comparison/split-view.htmltemplates/comparison/feature-matrix.htmlApply visual depth techniques based on the detected animation level. These are on by default — not optional extras.
| Technique | Minimal | Balanced | Dramatic |
|---|---|---|---|
Card accent borders (.card-accent) | Yes | Yes | Yes |
Badge labels (.badge) | Yes | Yes | Yes |
Tight heading typography (.tight-heading) | Yes | Yes | Yes |
Background grid (.bg-grid) | No | Yes | Yes |
Staggered reveal animations (.reveal) | No | Yes | Yes |
Section labels (.section-label) | No | Yes | Yes |
Glow effects (.glow) | No | No | Yes |
Glow pulse (.glow-pulse) | No | No | Yes |
How to apply:
bg-grid class to .slides-container for Balanced/Dramatic levelsreveal class to content elements inside slides (cards, list items, diagram blocks) for Balanced/Dramaticcard-accent or card-top-accent to card elementsbadge classes for labels, step numbers, and status indicatorsglow to key accent elements for Dramatic leveltight-heading on main headings for tighter letter-spacinginline-code class for short code references in text (e.g., FallbackModel(...))See references/style-guide.md "Visual Depth Techniques" section for full details.
When generating code slides:
<code> elements: <code class="language-python">Prism.highlightAll() in the initialization script after DOM readyFallbackModel(...) in a paragraph), use <code class="inline-code"> — do NOT create a separate code blockSee references/code-highlighting.md for Prism.js initialization requirements.
Before writing the final HTML file, perform these checks. This takes 30 seconds and prevents silent visual regressions.
#### Check 1: Class Integrity
Scan every class="..." attribute in the generated HTML. For each class name:
viewport-base.css? → OK<style> block? → OK<style> or use the correct existing class name.Common traps:
| Wrong (invented) | Fix |
|---|---|
section-label | Available in viewport-base.css — use directly |
metric-card | Define .metric-card in <style>, or use .kpi-card from KPI template |
slide-header | Use <h2> element (already styled by viewport-base.css) |
highlight | Define .highlight in <style> with specific styles |
content-box | Use .slide-content or .card |
#### Check 2: Inline Style Audit
Count style=" occurrences across all slides. Calculate per-slide average.
style="color: ...", style="font-size: ...", style="display: flex; gap: ..."#### Check 3: Repeating Pattern Detection
Search for any inline style value that appears on 3+ elements. Extract to a class:
style="font-size: 0.85rem; color: rgba(255,255,255,0.6)" → .muted-text classstyle="display: flex; gap: 1rem; align-items: center" → .flex-row .gap-md or custom classstyle="background: rgba(255,255,255,0.05); border-radius: 8px; padding: 1rem" → .surface-card class#### Check 4: Theme Variable Usage
Verify that custom CSS classes use theme variables, not hard-coded values:
var(--color-accent) not #89b4favar(--spacing-md) not 1.25remvar(--font-mono) not 'JetBrains Mono'var(--radius) not 12pxThis ensures the presentation respects the chosen theme and can be re-themed by changing :root variables.
presentation.html)If the user provides numbers in their message, extract and structure them:
If the user pastes or references structured data:
If the user describes data without specific numbers:
These apply to EVERY slide in EVERY presentation:
.slide has height: 100vh; height: 100dvh; overflow: hidden;clamp(min, preferred, max) — never fixed px/remmax-height: min(50vh, 400px); width: auto; object-fit: contain;max-height: min(55vh, 420px)max-height: min(60vh, 450px)max-height: min(55vh, 400px); overflow: hidden;prefers-reduced-motion supportcalc(-1 * clamp(...))If content doesn't fit → split into multiple slides. Never scroll.
These rules prevent the #1 cause of post-generation cleanup.
position: absolute; top: 15%; left: 60%style="--stagger-index: 3" or style="animation-delay: 0.3s"fill, stroke, transform inside <svg> elementsBefore writing style="..." on an element, check:
If all three answers are "no", the inline style is acceptable.
When creating a new slide type (metric cards, section headers, tech stack grids, etc.):
var(--color-accent), var(--spacing-md), etc.).card.highlight, .step.active)prefers-reduced-motion: disable all animations and transitions@media print: clean print output, one slide per pagearia-label on interactive elements (chart canvases, nav buttons)This skill works across AI coding tools. Some capabilities vary:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.