AgentStack
SKILL verified MIT Self-run

Revealjs Presentation

skill-zocomputer-skills-revealjs-presentation · by zocomputer

|

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add skill-zocomputer-skills-revealjs-presentation

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Revealjs Presentation? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Reveal.js Presentation Skill

Build self-contained HTML slide decks using Reveal.js 5 + Chart.js 4. Every output is a single .html file that opens in any browser. Optionally publish to zo.space as a live page route.

Two Output Modes

1. Local HTML File (default)

Creates a single .html file saved to the user's workspace. No build step, no dependencies. Open in any browser.

2. zo.space Page Route (on request)

Publishes the presentation as a live page on the user's .zo.space. Uses the pre-installed reveal.js package + inline styles. Use when the user says "publish", "put it on zo.space", "make it live", or "share it online".

The publish script at scripts/publish.ts handles the conversion from local HTML to a zo.space-compatible React page route. Run it via:

bun /home/workspace/Skills/revealjs-presentation/scripts/publish.ts --file  --route  [--public]

When publishing to zo.space:

  • Reveal.js is imported from the pre-installed package (import Reveal from "reveal.js")
  • Chart.js is loaded from CDN via dynamic script injection in useEffect
  • All CSS is inlined in the component
  • The route defaults to private unless --public is passed
  • After publishing, check get_space_errors() for build issues

Core Stack (Local HTML)

| Library | CDN | Purpose | |---------|-----|---------| | Reveal.js 5.1 | cdn.jsdelivr.net/npm/reveal.js@5.1.0 | Slide engine | | Chart.js 4.4 | cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js | Charts | | Google Fonts | fonts.googleapis.com | Typography |


Approved Extension Libraries

Reach for these when the core stack can't cover the requirement. All are CDN-loadable and UMD-compatible.

Data Visualization

| Need | Library | CDN | |------|---------|-----| | Custom charts | D3.js v7 | cdn.jsdelivr.net/npm/d3@7 | | Animated counters | CountUp.js | cdn.jsdelivr.net/npm/countup.js@2 | | Geographic maps | Leaflet.js | cdn.jsdelivr.net/npm/leaflet@1.9 | | Flow diagrams | Mermaid.js | cdn.jsdelivr.net/npm/mermaid@10 |

Animation & Motion

| Need | Library | CDN | |------|---------|-----| | Complex sequences | GSAP | cdn.jsdelivr.net/npm/gsap@3 | | Particle backgrounds | tsParticles | cdn.jsdelivr.net/npm/tsparticles@2 | | Typewriter effect | Typed.js | cdn.jsdelivr.net/npm/typed.js@2 | | Lottie animations | lottie-web | cdn.jsdelivr.net/npm/lottie-web@5 |

Content & Code

| Need | Library | CDN | |------|---------|-----| | Code highlighting | Prism.js | cdn.jsdelivr.net/npm/prismjs@1 | | Math / LaTeX | MathJax 3 | cdn.jsdelivr.net/npm/mathjax@3 | | Icons | Lucide | unpkg.com/lucide@latest/dist/umd/lucide.js |


Compatibility Checks for New Libraries

Before adding any library not listed above:

  1. Can CSS or existing stack handle it? Many effects don't need a library.
  2. UMD build on CDN? Must work via `` tag. ES module-only packages won't work.
  3. No conflict with Reveal.js? Watch for global keyboard/scroll listeners, body transform manipulation.
  4. Init after slide visible? Use slidechanged event handler, not DOMContentLoaded.
  5. **

fonts → reveal.css → theme → chart.js →

SVG symbol defs (logos, icons)

x N slides

reveal.js script → init script → chart build functions


---

## Boilerplate Shell

```html

PRESENTATION TITLE

:root {
  --bg:    #FAFAF8;
  --dk:    #111111;
  --dk2:   #333333;
  --gray:  #888888;
  --accent:#YOUR_COLOR;
  --border:#E5E5E5;
  --f-sans:'YOUR_FONT', system-ui, sans-serif;
  --f-mono:'YOUR_MONO', 'SF Mono', monospace;
}

.reveal { font-family: var(--f-sans); }
.reveal .slides section {
  text-align: left;
  height: 100%;
  padding: 0;
}

.S {
  position: relative;
  width: 100%; height: 100%;
  display: flex; flex-direction: column;
  padding: 32px 52px 24px;
  overflow: hidden;
  background: var(--bg);
  color: var(--dk);
  box-sizing: border-box;
}
.S > * { position: relative; z-index: 1; }

.pre { opacity: 0; }
.al  { animation: fromLeft  .5s ease forwards; }
.ar  { animation: fromRight .5s ease forwards; }
.ab  { animation: fromBelow .5s ease forwards; }
.af  { animation: fadeUp    .55s ease forwards; }
.ap  { animation: pop       .4s ease forwards; }

.d1 { animation-delay:.08s }
.d2 { animation-delay:.18s }
.d3 { animation-delay:.28s }
.d4 { animation-delay:.38s }
.d5 { animation-delay:.48s }
.d6 { animation-delay:.58s }

@keyframes fromLeft  { from{opacity:0;transform:translateX(-22px)} to{opacity:1;transform:none} }
@keyframes fromRight { from{opacity:0;transform:translateX(22px)}  to{opacity:1;transform:none} }
@keyframes fromBelow { from{opacity:0;transform:translateY(18px)}  to{opacity:1;transform:none} }
@keyframes fadeUp    { from{opacity:0}                             to{opacity:1} }
@keyframes pop       { from{opacity:0;transform:scale(.93)}        to{opacity:1;transform:scale(1)} }

.cw {
  position: relative;
  width: 100%;
  min-height: 200px;
  flex-shrink: 0;
}
.cw canvas {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
}

.h1 { font-size:52px; font-weight:800; line-height:1.05; }
.h2 { font-size:38px; font-weight:700; line-height:1.1;  }
.h3 { font-size:28px; font-weight:700; line-height:1.15; }
.stag {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .25em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}
.mono { font-family: var(--f-mono); }

.row { display:flex; flex-direction:row; gap:24px; }
.col { display:flex; flex-direction:column; gap:12px; }
.g2  { display:grid; grid-template-columns:1fr 1fr;         gap:12px; }
.g3  { display:grid; grid-template-columns:1fr 1fr 1fr;     gap:12px; }
.g4  { display:grid; grid-template-columns:1fr 1fr 1fr 1fr; gap:12px; }

.card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 20px;
}
.card.accent {
  background: var(--accent);
  color: #fff;
  border: none;
}

.pill {
  display:inline-flex; align-items:center;
  padding:3px 10px; border-radius:99px;
  font-size:11px; font-weight:600; letter-spacing:.03em;
  background: rgba(0,0,0,.07);
}

  

const chartMap = {};
const built = new Set();

Reveal.initialize({
  hash: true,
  transition: 'fade',
  transitionSpeed: 'fast',
  controls: true,
  progress: true,
  width: 1280,
  height: 720,
  margin: 0,
});

function animateSlide(slide) {
  slide.querySelectorAll('.pre').forEach(el => el.classList.remove('pre'));
}

Reveal.on('slidechanged', ({ indexh }) => {
  const slide = Reveal.getSlide(indexh);
  if (slide) animateSlide(slide);
  if (chartMap[indexh] && !built.has(indexh)) {
    built.add(indexh);
    chartMap[indexh]();
  }
});

Reveal.on('ready', () => {
  const slide = Reveal.getSlide(0);
  if (slide) animateSlide(slide);
  if (chartMap[0] && !built.has(0)) {
    built.add(0);
    chartMap[0]();
  }
});

Slide Anatomy

Every slide follows this pattern:


  Category
  Headline with accent
  
    Supporting text.
  
  
    
  

Layout Patterns

2-Column Split


  
  

Card Grid (3-up)


  ...
  ...
  ...

Hero Stat


  $5.2B
  market

CSS Treemap


  
    
      Category
      34%
    
  

Numbered Steps / Timeline


  
  
    1
    Step Title
    Description
  

Comparison Table (CSS grid)


  Feature
  Option A
  Option B
  Feature name
  No
  Yes

Chart.js Recipes

Bar Chart

function buildBarChart() {
  const ctx = document.getElementById('barChart').getContext('2d');
  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
      datasets: [{
        label: 'Revenue',
        data: [42, 68, 55, 89, 104, 127],
        backgroundColor: 'YOUR_COLOR',
        borderRadius: 6,
        borderSkipped: false,
      }]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      plugins: { legend: { display: false } },
      scales: {
        x: { grid: { display: false }, border: { display: false } },
        y: { grid: { color: '#f0f0f0' }, border: { display: false } }
      }
    }
  });
}

Line Chart

function buildLineChart() {
  const ctx = document.getElementById('lineChart').getContext('2d');
  new Chart(ctx, {
    type: 'line',
    data: {
      labels: ['Q1', 'Q2', 'Q3', 'Q4'],
      datasets: [{
        label: 'Series A',
        data: [30, 55, 80, 120],
        borderColor: 'YOUR_COLOR_1',
        backgroundColor: 'YOUR_COLOR_1_20',
        borderWidth: 2.5,
        pointRadius: 4,
        tension: 0.35,
        fill: true,
      }]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      scales: {
        x: { grid: { display: false } },
        y: { grid: { color: '#f0f0f0' } }
      }
    }
  });
}

Doughnut

function buildDoughnut() {
  const ctx = document.getElementById('doughnutChart').getContext('2d');
  new Chart(ctx, {
    type: 'doughnut',
    data: {
      labels: ['A', 'B', 'C'],
      datasets: [{
        data: [40, 30, 30],
        backgroundColor: ['#C1','#C2','#C3'],
        borderWidth: 0,
      }]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      cutout: '65%',
    }
  });
}

Canvas HTML:


  

Register in chartMap:

const chartMap = { 3: buildFunnelChart, 7: buildLineChart };

Animation Rules

  1. Add .pre to any element to start invisible
  2. Add direction: .al (left), .ar (right), .ab (below), .af (fade), .ap (pop)
  3. Add delay: .d1 through .d6
  4. Init script removes .pre when slide becomes active

Critical Gotchas

  • Chart height must be explicit. .cw wrappers need min-height. Chart.js reads container height; 0px = invisible.
  • Dead functions = errors. Every chartMap entry needs a matching ``.
  • Don't reuse canvas IDs. Each chart needs a unique ID.
  • SVG logos: define once, use everywhere with ` and `.
  • Reveal.js default is 960x700. For widescreen: width: 1280, height: 720.

Slide Type Catalog

| Type | Best For | |------|----------| | Hero / Title | Opening, closing | | Stat Showcase | Key metrics | | Problem / Opportunity | Setting context | | Feature Grid | Capability overview | | Comparison | Competitive positioning | | Chart | Data storytelling | | Process / Steps | How it works | | Timeline | Roadmap | | Quote / Testimonial | Social proof | | Closing / CTA | Next steps |


Publishing to zo.space

When the user wants to publish a presentation to zo.space:

  1. First create the local HTML file as normal
  2. Run the publish script:

``bash bun /home/workspace/Skills/revealjs-presentation/scripts/publish.ts \ --file /home/workspace/Inbox/my-deck.html \ --route /presentations/my-deck \ --public ``

  1. The script extracts slides HTML, CSS variables, custom styles, chart functions, and SVG symbols from the HTML file
  2. It generates a React page route component that:
  • Imports Reveal.js from the pre-installed package
  • Loads Chart.js from CDN dynamically if charts are present
  • Inlines all custom CSS
  • Initializes Reveal.js in a useEffect
  • Handles animations and chart building
  1. The route is deployed via update_space_route
  2. Check get_space_errors() after publishing

The published presentation will be live at https://.zo.space.

Manual zo.space Publishing (without the script)

If you need more control, you can manually create a page route. The pattern:

import { useEffect, useRef } from "react";
import Reveal from "reveal.js";

export default function Presentation() {
  const deckRef = useRef(null);
  const revealRef = useRef(null);

  useEffect(() => {
    // Load reveal.js CSS from CDN
    const revealCss = document.createElement("link");
    revealCss.rel = "stylesheet";
    revealCss.href = "https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/reveal.css";
    document.head.appendChild(revealCss);

    const themeCss = document.createElement("link");
    themeCss.rel = "stylesheet";
    themeCss.href = "https://cdn.jsdelivr.net/npm/reveal.js@5.1.0/dist/theme/white.css";
    document.head.appendChild(themeCss);

    // Init Reveal after CSS loads
    themeCss.onload = () => {
      if (deckRef.current && !revealRef.current) {
        const deck = new Reveal(deckRef.current, {
          hash: true,
          transition: "fade",
          transitionSpeed: "fast",
          controls: true,
          progress: true,
          width: 1280,
          height: 720,
          margin: 0,
          embedded: false,
        });
        deck.initialize();
        revealRef.current = deck;
      }
    };

    return () => {
      revealRef.current?.destroy();
      revealCss.remove();
      themeCss.remove();
    };
  }, []);

  return (
    <>
      {`
        /* your custom CSS here */
      `}
      
        
          {/*  slides here  */}
        
      
    
  );
}

Quick-Start Checklist

Before writing slides:

  • [ ] Define CSS variables: --bg, --dk, --accent, --f-sans, --f-mono
  • [ ] Choose font pair and add Google Fonts import
  • [ ] Plan slide count and sequence
  • [ ] Identify charts and assign unique canvas IDs
  • [ ] Identify logos/icons to SVG-symbolize

When writing each slide:

  • [ ] Wrap in ``
  • [ ] Add .pre + animation class + delay to animated elements
  • [ ] Use explicit min-height on .cw chart wrappers

After all slides:

  • [ ] Build chartMap with 0-based slide indices
  • [ ] One buildXxx() per chart
  • [ ] Every chartMap key has a matching ``
  • [ ] If publishing to zo.space, run publish script

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.