Install
$ agentstack add skill-joao-aires-skills-presentation-building ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
About
Presentation Builder
Create polished, single-file HTML slide presentations optimised for widescreen and fullscreen delivery.
When to Use
Use this skill when asked to:
- create a new presentation from scratch
- add, edit, reorder, or remove slides
- fix layout, overflow, or fullscreen rendering issues
- add or modify optional addons (e.g. the vertical timeline navigation)
- create card grids, comparison layouts, or diagrams
- embed images, tweets, or interactive elements
- refine typography, spacing, or visual consistency across slides
Architecture Overview
Each presentation is a single index.html file containing all markup, CSS, and JavaScript inline. No build step is required. Assets (images) live in an attachments/ directory alongside the HTML file.
presentation/
index.html # The entire presentation
attachments/ # Images referenced by slides
3.png
...
Self-contained addon reference files live under references/addons/. Each addon bundles the CSS, HTML, and JS required to extend the base skeleton.
Key Technical Decisions
- Single file — everything in one HTML file for portability
- No frameworks — vanilla HTML, CSS, and JS only
- Dark theme — dark background with light text, always
- Vertical scroll — slides are full-viewport `` elements stacked vertically
- Addon-based extensions — optional features (e.g. timeline navigation) are self-contained addon files that merge into the base skeleton
- Responsive by default —
clamp()throughout; slides work on most screens, optimised for widescreen (16:9 to ultrawide) - Fullscreen support — press
Fto toggle; dense slides usefit-wideauto-scaling
Design System
Colour Palette
:root {
--bg: #0a0a12;
--surface: #12121e;
--surface-alt: #181828;
--border: #1e1e30;
--text: #e8e8f0;
--text-muted: #8888a0;
--accent: #4ecdc4; /* Teal — primary accent */
--accent-dim: rgba(78, 205, 196, 0.15);
--red: #ff6b6b;
--yellow: #ffd93d;
--purple: #a78bfa;
--blue: #60a5fa;
--font-sans: "Inter", system-ui, sans-serif;
--font-mono: "JetBrains Mono", monospace;
}
Use named CSS variables everywhere. Never use raw hex colours in slide markup.
Typography
- Font: Inter (sans-serif) for all text, JetBrains Mono for code and monospace elements
- Headings: Use
clamp()for all font sizes — specify(min, preferred, max) - h1: Title slides only.
clamp(2.4rem, 4.5vw, 5rem), weight 700 - h2: Slide titles.
clamp(1.5rem, 2.8vw, 3.2rem), weight 600 - h3: Eyebrow/section labels above
h2. Uppercase, letter-spacing.08em, accent colour - Body text:
clamp(.88rem, 1.3vw, 1.4rem)for bullet lists - Strong text inside bullets: Use
color: var(--accent)for emphasis
Spacing
- Use
clamp()for all padding, margins, and gaps - Pattern:
clamp(min, preferred-vw-or-vh, max) - Never use fixed pixel values for layout spacing
Customisation
The design system above defines defaults, not constraints. When the user requests a different visual style or new components, adapt accordingly:
Colour changes: If the user wants a different accent colour, light theme, or custom palette — update the :root CSS variables. All components use variables, so a single change propagates everywhere. Keep the variable naming convention (--accent, --surface, etc.) and update the values.
Typography changes: If the user wants a different font, weight scheme, or sizing — update the --font-sans / --font-mono variables, adjust the clamp() values, and update the Google Fonts `. The clamp(min, preferred, max)` pattern should always be used regardless of the specific font.
New components: When the user asks for a component that doesn't exist in the catalog (e.g. a comparison table, a code block, a quote callout, a stat counter) — create it inline following these rules:
- Use CSS variables for colours — never hardcode hex values
- Use
clamp()for all sizing and spacing - Use the existing border-radius (
8px–12px), background (var(--surface)), and border (var(--border)) patterns for visual consistency - Apply
.revealor.reveal-staggerfor scroll animation - Add the component's CSS in the slide-specific CSS section or, if reused across slides, in the main `` block
Layout modifications: If the user wants multi-column layouts, split views, or non-standard arrangements — build them with CSS grid or flexbox inline. Keep the .scene / .scene-inner wrapper structure and add layout rules either as inline styles or slide-specific CSS.
Slide transitions or effects: The default is scroll-driven reveal. If the user wants different animations (e.g. fade-in from left, scale-up, typewriter) — create new CSS classes following the .reveal pattern: hidden by default, .visible state applied by the existing IntersectionObserver.
The principle: match the user's vision while maintaining the technical conventions (single file, CSS variables, clamp(), responsive behaviour, no frameworks).
Slide Structure
Basic Slide
Every slide is a ` containing a `:
Section Label
Slide Title
Rules:
- Every slide gets a unique
idprefixed withs- - When using the timeline addon, add
data-tlto link the slide to its timeline event - Always include a numbered HTML comment block above each slide for navigation
h3is the section eyebrow (e.g., "The impact", "Tips & tricks"),h2is the slide title
Slide Types and Classes
| Class | Purpose | | ---------------------------- | --------------------------------------------------------- | | .scene | Base slide — vertically centred content | | .scene.fit-wide | Dense slides — enables JS auto-scaling for fullscreen | | .scene.fullscreen-balanced | Card-heavy slides — uses flexbox layout in wide viewports |
.fit-wide enables fitWideSlides() JS that scales .scene-inner down (min 0.82×) when content overflows the viewport. Use for slides with lots of content that must be visible without scrolling.
.fullscreen-balanced adds CSS media queries that make .scene-inner flex-column and expand card grids. Use for slides with 2–4 cards that should fill the viewport evenly.
Component Catalog
All components below are available in the base skeleton. Choose the component that best fits your content type.
Title Slide — .title-slide
When to use: First slide of every presentation. Sets the topic, author, and context.
EVENT_TAG · DATE
Presentation Title
A supporting one-liner that frames the talk
Author Name · Role
Sub-elements:
.tag— monospace label above the title (event name, date, category). Use for situational context the audience needs before reading the title..subtitle— lighter, thinner text belowh1. One sentence max. Use to qualify or narrow the title's scope..meta— small muted text for author, role, team, or date. Appears below the subtitle.
Closing / Q&A Slide — .qa-slide
When to use: Last slide. Signals the end and opens the floor.
Q&A
Thank you!
Centre-aligned, large heading. Keep it minimal — no bullets or cards.
Bullet Lists — .bullet-list
When to use: Presenting 3–5 key points, arguments, or takeaways in sequence. The default choice when content is narrative or explanatory.
Bold lead phrase — supporting detail
Regular bullet point
Sub-bullet with emphasis
Another sub-point — use – marker
Conventions:
- Bullets use
›markers (via CSS::before), sub-bullets use– - Keep main bullets to 3–5 per slide
- `
inside bullets renders invar(--accent)` colour
Card Grids — .card-grid + .card
When to use: Comparing features, tools, options, or categories side by side. Best for 2–6 items of roughly equal weight that the audience should scan in parallel rather than read in order.
Card Title
Card description text.
Another Card
Bold item — detail
Another item
Conventions:
- Use
border-top: 3px solid var(--colour)for visual distinction between cards - Card bullets use
›markers (same as pillar cards) - Keep card content concise — 3–5 bullet points max
- Cards auto-fit:
grid-template-columns: repeat(auto-fit, minmax(clamp(200px, 18vw, 300px), 1fr)) - For 5+ cards or dense content, add
fit-wideto the slide and usefullscreen-balancedfor 2–4 cards
Pillar Cards — .pillar-grid + .pillar-card
When to use: Presenting strategic pillars, principles, or structured categories that each have a title, optional tagline, and bullet details. Prefer over plain cards when each item needs a clear header + subtitle hierarchy.
Pillar Name
Tagline or subtitle
Bullet with emphasis
Another point
Pillar cards are the preferred visual reference for informational card styling. When normalising card styles across a deck, use pillar cards as the benchmark:
- Lighter background:
rgba(255, 255, 255, .02) - Softer borders:
rgba(255, 255, 255, .08) - 12px border-radius
›bullet markers in accent colour- Fixed 3-column grid (
repeat(3, 1fr)) — adjust count if needed
Timeline Event Slides — .event-slide
When to use: A slide anchored to a specific date or milestone. Typically used with the timeline addon but works standalone for any chronological narrative. Pair with the event marker (coloured dot + vertical line) to visually anchor the date.
Month Year
Event Title
Key point about this event
Conventions:
- Colour the
.edotand.elinewith the appropriate theme colour for the event - `` is monospace, muted — shows "Month Year" above the title
- `` is optional — for screenshots or diagrams related to the event
Image Cards with Hover Preview — .card.has-preview
When to use: Cards that reference a tool, page, or visual artefact the audience may want to see. The preview image appears on hover/focus, useful for demo screenshots or UI references without cluttering the slide.
Card Title
Description
Caption text
Conventions:
- Add
tabindex="0"so keyboard users can trigger the preview - For wide/fullscreen, position previews to the right side with slide-specific CSS media queries
Tweet Embeds
When to use: Quoting a public statement, announcement, or reaction from social media. Adds credibility and a visual break from bullets/cards.
Tweet text...
— Author (@handle)
Date
Conventions:
- The Twitter widgets script is loaded once globally at the end of the file — never duplicate it inside individual slides
- Always use
data-theme="dark"to match the presentation theme
Eyebrow + Title Pattern — h3 + h2
When to use: Every content slide. The h3 eyebrow provides section continuity across slides (e.g. "The problem", "Our approach", "Results") while h2 is the unique slide title.
Section Label
Slide Title
Conventions:
h3is uppercase, accent-coloured, letter-spaced — acts as a section grouping labelh2is the main title — apply.revealfor scroll animation- Keep the same
h3across slides that belong to the same narrative section
Diagrams — inline SVG or HTML/CSS
When to use: Showing architecture, flows, relationships, or processes that are clearer as a visual than as bullets or cards. Use when the audience needs to see how things connect rather than just what they are.
Diagrams are built inline using either HTML/CSS boxes with flexbox/grid or inline SVG. Never use external diagram tools or images for diagrams that could be drawn with code — keeps them resolution-independent and theme-consistent.
HTML/CSS approach (preferred for box-and-arrow layouts):
Box A
Description
→
Box B
Description
Inline SVG approach (for complex paths, arrows, or non-linear layouts):
Service A
Service B
Conventions:
- Use CSS variables for all colours —
var(--surface),var(--border),var(--accent), etc. - Use
clamp()for sizing and spacing in the HTML/CSS approach - Use
viewBoxfor SVGs so they scale responsively - Arrows: use
→character for simple flows, SVG `` for complex connectors - Keep diagrams to 3–6 nodes — more than that needs a dedicated slide or simplification
- Apply
.revealto the diagram container for scroll animation - Colour-code nodes by role using the theme palette (accent for primary, purple for secondary, blue for tertiary, etc.)
Reveal Animations
Two animation systems:
.reveal— single element fade-up on scroll.reveal-stagger— container whose children animate in sequence
Title fades in
Critical: The stagger system defines explicit nth-child delays for children 1–6. A catch-all rule ensures children 7+ are also visible (just without stagger delay). If a grid has more than 6 children, verify they all appear.
The reveal system uses IntersectionObserver with a 12% threshold to add the .visible class.
Addons
Addons are optional, self-contained feature packages that extend the base presentation skeleton. Each addon lives as a single reference file under references/addons/.html containing all the CSS, HTML, and JS needed.
When to Include an Addon
Include an addon when:
- The user explicitly requests the feature
- The content naturally calls for it (e.g. chronological data → timeline)
Omit when:
- The presentation is short or non-chronological (timeline)
- The user wants a minimal deck
Addon File Convention
Each addon file contains:
- Header comment — name, purpose, and integration points
- CSS section — styles to merge into `
, plus any:root` variable additions - HTML section — markup to insert at the specified location
- JS section — code to merge into the main `` IIFE
Integration points are documented per-addon in the header comment. When applying an addon, merge each section into the corresponding location in the skeleton rather than pasting the addon file verbatim.
Available Addons
Timeline Navigation
Reference: [references/addons/timeline.html](references/addons/timeline.html)
A fixed right-side vertical rail with chronological event labels, year markers, SVG leader-line connectors, and progressive disclosure tied to scroll position.
When to use: The content is chronological, has 5+ events spanning multiple dates, or the user requests a timeline.
Integration points (documented in the file header):
:rootvariables — add--nav-wand--rail-x.scenepadding — addpadding-right: calc(var(--nav-w) + clamp(...))- Slide counter — shift right by
--nav-w - `` HTML — insert before the slide counter
data-tlattribute — add to each `` to link slides to events- JS — merge
positionTimeline(), progressive disclosure, andupdateTimeline()into the main IIFE; callupdateTimeline(idx)from the existing scroll handler
Structure:
- Year markers (centred on rail) — positioned by
data-date - Right-side events — clickable, linked to slides via
data-target - Left-side events (
tl-left) — secondary track, purple-tinted; clickable by default - Annotations (
tl-left tl-secondary) — non-interactive left-side labels with smaller font, optional.badge
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: joao-aires
- Source: joao-aires/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.