
Presentation
- 90 installs
- 68 repo stars
- Updated July 13, 2026
- thedesignproject/agent-skills
Use when working on frontend tasks.
About
presentation is a specialized Claude Code skill supporting git & pull requests development. Designed for efficient workflow automation and integration across development domains.
- Presentation
Presentation by the numbers
- 90 all-time installs (skills.sh)
- +12 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #273 of 792 Skill Development skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedesignproject/agent-skills --skill presentationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 90 |
|---|---|
| repo stars | ★ 68 |
| Last updated | July 13, 2026 |
| Repository | thedesignproject/agent-skills ↗ |
What it does
Use when working on frontend tasks.
Files
Presentation Skill
Creates standalone HTML slide deck presentations with CSS animations, keyboard/click/swipe navigation, bullet reveal, mouse parallax, and polished visual design. Single file, no dependencies, works anywhere.
---
Step 1: Choose a Mode
Ask the user how they want to work:
- Full generation: User provides content/outline upfront → Claude generates the entire presentation in one shot. Best when the user already knows what they want to say.
- Interactive step-by-step: Claude scaffolds the framework first, then builds slides one at a time — user reviews each slide before moving to the next. Best when the user is still figuring out the story or wants tight control.
---
Step 2: Content & Structure (THE MOST IMPORTANT STEP)
Before writing any code, deeply understand what the presentation is actually saying.
Ask the user to provide source material — any of:
- A document, outline, or notes about the topic
- A rough slide-by-slide outline
- Key talking points, stats, or quotes
- An existing presentation to redesign
- A brain dump of everything they want to cover
Then collaboratively build the slide outline:
- For each slide: choose a type, headline, body content, and special elements
- Suggest a narrative arc: hook → context → key content → details → closing
- Flag where bullet-reveal slides help (dense content needing progressive disclosure)
- Identify which slides need images/assets vs. pure text
- Confirm final slide count and order before proceeding
This step makes or breaks the presentation. Spend the most time here.
Available slide types
| Type | Class | Use Case |
|---|---|---|
| Title | .slide-title | Opening — large heading, subtitle, decorative shapes |
| Speaker/Bio | .slide-speaker | Introduce presenter — avatar, name, role, glass card |
| Question | .slide-familiar | Audience engagement — large centered question |
| Bullet Reveal | .slide-learn | Key points, agendas — progressive reveal with data-bullets |
| Tool/Badge Grid | .slide-setup | Tools, tech, logos — grid of badge cards |
| Workflow/Flow | .slide-flow | Processes, steps — connected boxes with arrows |
| Two-Column | .slide-llm | Text + image — split layout |
| Team/Grid | .slide-speakers | Meet the team — photo grid with names/roles |
| Glossary | .slide-gloss | Definitions — large term + definition |
| Closing/CTA | .slide-closing | Final slide — large text, call to action |
For detailed HTML templates of each type, see slide-types.md.
---
Step 3: Design Brief
Gather style direction from the user:
- Colors: brand colors, or suggest a palette (5-6 hex values with roles: primary, secondary, accent, background-light, background-dark, text)
- Fonts: heading + body font families (Google Fonts or system fonts)
- Vibe: minimal / editorial / glassmorphism / bold / corporate
- Assets: logos, images, photos to embed
Produce a brief with:
- Color palette with CSS variable names and hex values
- Typography scale (heading-xl, heading-lg, heading-md, subtitle, body-text)
- Font families and weights
- Spacing rhythm (slide padding, element gaps)
- Animation style (subtle vs. dramatic)
- One-sentence visual direction
- Slide-to-theme mapping (which slides get which background color)
For CSS/typography/animation defaults and templates, see framework-reference.md.
---
Step 4: Generate the Framework
Create a single standalone HTML file with embedded <style> and <script>.
The file structure is:
<!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>
[Google Fonts link]
<style>
/* Reset, design tokens, slide system, themes, shapes,
animations, typography, UI chrome, slide-specific styles,
responsive breakpoint */
</style>
</head>
<body>
<div class="presentation">
<!-- Slides go here -->
</div>
<!-- Progress bar, slide counter, nav hint -->
<script>
/* IIFE-based navigation engine */
</script>
</body>
</html>For the complete CSS architecture and JS navigation engine templates, see framework-reference.md.
---
Step 5: Build Slides
Using the templates from slide-types.md:
- Full generation mode: Create all slides at once based on the outline from Step 2
- Interactive mode: One slide at a time — write the HTML, let the user review, adjust, then move to the next
For every slide: 1. Use the appropriate section.slide with theme class (.slide--primary, .slide--secondary, .slide--light) 2. Set data-theme="dark" or data-theme="light" for nav UI color adaptation 3. Add .anim classes to all content elements for entrance animations 4. Apply stagger delays (.anim-d1 through .anim-d8) in visual reading order 5. Add decorative shapes with entrance directions (.shape-enter-left, etc.) 6. Include .slide-footer with consistent content on every slide 7. For bullet-reveal slides: set data-bullets="N" and use <li data-bullet="N"> elements
---
Step 6: Polish & Review
Checklist before delivery:
- [ ] All
.animclasses present on content elements - [ ] Stagger delays follow visual reading order
- [ ] Decorative shapes don't overlap content (use
z-indexlayering) - [ ] Color contrast is correct on all slide themes
- [ ] Bullet reveal count matches
data-bulletsattribute - [ ] Responsive layout works at 768px breakpoint
- [ ] Navigation works: keyboard (arrows, Space, PgUp/Dn, Home, End), click (left 30% = back, right 70% = forward), and touch/swipe (>50px threshold)
- [ ] Progress bar and slide counter update correctly
- [ ] Header/footer chrome consistent across slides
- [ ] All fonts load correctly (Google Fonts or fallbacks)
---
Step 7: Export
Default: standalone HTML — single file with base64-embedded images and assets. Works anywhere, no server needed.
To embed images as base64:
<img src="data:image/png;base64,[base64-data]" alt="...">Optionally offer:
- Dev version: external image references for easier editing
- Individual slides: separate HTML files per slide for modular use
---
Key Patterns
For design patterns, animation tips, and hard-won insights from building presentations with this framework, see learnings.md.
Quick reference
- Easing:
cubic-bezier(0.16, 1, 0.3, 1)(expo-out) for all transitions - Stagger:
.anim-d1(0.1s) through.anim-d8(1.1s) - Shapes: absolute positioned,
mix-blend-mode: overlay, floating keyframe animations - Glass:
backdrop-filter: blur(28px)+ semi-transparent white + subtle border - Typography:
clamp()for fluid sizing across projector/laptop/tablet - Parallax:
--mx/--myCSS variables tracked on mousemove - Transitions: 700ms lockout via
isTransitioningflag
Framework Reference
Detailed CSS architecture and JS navigation engine templates for the presentation framework. Load this file when building the framework (Step 4).
---
CSS Architecture
Reset & Base
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; }
body {
font-family: '[heading-font]', system-ui, -apple-system, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}Design Tokens (CSS Custom Properties)
Adapt the color names and values to the presentation's design brief. The structure should always include:
:root {
/* Colors — adapt names and values per project */
--primary: #5B5BF0;
--primary-dark: #4A4AD0;
--primary-light: #7B7BFF;
--secondary: #FF6B47;
--secondary-light: #FF8A6A;
--light: #FAF5F0;
--light-dark: #F0E8E0;
--white: #FFFFFF;
--dark: #2D2D2D;
--dark-muted: #555555;
/* Fonts — adapt per project */
--font-heading: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-serif: 'Playfair Display', Georgia, serif;
--font-body: 'Plus Jakarta Sans', system-ui, sans-serif;
/* Easing — these are battle-tested, rarely need changing */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
/* Parallax mouse tracking */
--mx: 0;
--my: 0;
}Slide Container System
.presentation {
width: 100vw;
height: 100vh;
position: relative;
background: var(--dark);
}
.slide {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 60px 80px;
opacity: 0;
visibility: hidden;
transform: scale(0.96);
transition: opacity 0.7s var(--ease-out-expo),
transform 0.7s var(--ease-out-expo),
visibility 0s 0.7s;
overflow: hidden;
}
.slide.active {
opacity: 1;
visibility: visible;
transform: scale(1);
transition: opacity 0.7s var(--ease-out-expo),
transform 0.7s var(--ease-out-expo),
visibility 0s 0s;
}Background Theme Variants
Create theme classes for each brand color. Use radial gradients for depth.
.slide--primary {
background: var(--primary);
background-image:
radial-gradient(ellipse 65% 55% at 25% 35%, rgba(130,140,255,0.5) 0%, transparent 65%),
radial-gradient(ellipse 40% 35% at 80% 70%, rgba(70,50,190,0.45) 0%, transparent 55%);
color: var(--white);
}
.slide--secondary {
background: var(--secondary);
background-image:
radial-gradient(ellipse 45% 40% at 15% 65%, rgba(255,140,60,0.35) 0%, transparent 60%);
color: var(--white);
}
.slide--light { background: var(--light); color: var(--dark); }Each slide uses data-theme="dark" or data-theme="light" so the JS can adapt nav UI colors.
Slide Footer
.slide-footer {
position: absolute;
bottom: 2vh;
left: 4vw;
right: 4vw;
display: flex;
justify-content: space-between;
align-items: center;
font-size: clamp(10px, 1vw, 14px);
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
opacity: 0.5;
}
.slide--primary .slide-footer,
.slide--secondary .slide-footer { color: var(--white); }
.slide--light .slide-footer { color: var(--dark-muted); }Header Chrome
Optional top bar for branding. Applied per-slide as inline styles:
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(255,255,255,0.18); z-index:10; pointer-events:none;">
<span style="font-size:clamp(10px,1vw,14px); font-weight:600; letter-spacing:0.12em; text-transform:uppercase; opacity:0.5;">Left label</span>
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em;">Logo</span>
</div>For light-themed slides, use rgba(28,28,28,0.1) for the border and color:var(--dark) on text.
---
Decorative Shapes
Glass Shapes (CSS-only, for dark backgrounds)
.shape {
position: absolute;
pointer-events: none;
z-index: 0;
--parallax: 5;
transition: margin 0.4s ease-out;
}
.slide.active .shape {
margin-left: calc(var(--mx) * var(--parallax) * 1px);
margin-top: calc(var(--my) * var(--parallax) * 1px);
}
/* Glass pill */
.shape-pill {
width: 180px; height: 80px;
border-radius: 40px;
background: linear-gradient(135deg, rgba(255,255,255,0.25) 0%, rgba(255,255,255,0.08) 100%);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255,255,255,0.2);
box-shadow: 0 8px 32px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.3);
animation: float1 8s ease-in-out infinite;
}
/* Glass sphere */
.shape-sphere {
width: 140px; height: 140px;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, rgba(255,255,255,0.35) 0%, rgba(255,255,255,0.05) 70%);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
border: 1px solid rgba(255,255,255,0.15);
box-shadow: 0 12px 40px rgba(0,0,0,0.08), inset 0 -4px 12px rgba(255,255,255,0.1);
animation: float3 9s ease-in-out infinite;
}
/* Glass star */
.shape-star {
width: 120px; height: 120px;
background: linear-gradient(135deg, rgba(255,255,255,0.3) 0%, rgba(255,255,255,0.1) 100%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
filter: drop-shadow(0 4px 16px rgba(0,0,0,0.1));
animation: float2 10s ease-in-out infinite;
}Image-based Shapes
For using image assets as decorative shapes:
.shape-img {
mix-blend-mode: overlay;
object-fit: contain;
height: auto;
}Usage: position with inline styles, vary opacity, width, animation-delay, and mix-blend-mode: luminosity for subtlety.
Iridescent Variant (for light backgrounds)
.shape--iridescent {
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 30%, #fdfcfb 50%, #a8edea 70%, #fed6e3 100%) !important;
opacity: 0.7;
border: none !important;
box-shadow: 0 8px 32px rgba(255, 107, 71, 0.15), 0 2px 8px rgba(91, 91, 240, 0.1);
}Floating Keyframes
@keyframes float1 {
0%, 100% { transform: translateY(0px) rotate(0deg); }
33% { transform: translateY(-18px) rotate(5deg); }
66% { transform: translateY(8px) rotate(-3deg); }
}
@keyframes float2 {
0%, 100% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-25px) rotate(-8deg); }
}
@keyframes float3 {
0%, 100% { transform: translateY(0) rotate(0deg) scale(1); }
50% { transform: translateY(-15px) rotate(12deg) scale(1.03); }
}
@keyframes spin-slow {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes pulse-glow {
0%, 100% { opacity: 0.7; transform: scale(1); }
50% { opacity: 1; transform: scale(1.05); }
}Glassmorphism Panel
For glass card backgrounds behind content:
.glass-panel {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 91%; height: 88%;
background: rgba(255, 255, 255, 0.07);
backdrop-filter: blur(28px);
-webkit-backdrop-filter: blur(28px);
border-radius: 40px;
border: 1px solid rgba(255, 255, 255, 0.18);
z-index: 2;
pointer-events: none;
}---
Animation System
Entrance Animations
.slide .anim {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s var(--ease-out-expo), transform 0.6s var(--ease-out-expo);
}
.slide.active .anim {
opacity: 1;
transform: translateY(0);
}
/* Stagger delays */
.slide.active .anim-d1 { transition-delay: 0.1s; }
.slide.active .anim-d2 { transition-delay: 0.2s; }
.slide.active .anim-d3 { transition-delay: 0.35s; }
.slide.active .anim-d4 { transition-delay: 0.5s; }
.slide.active .anim-d5 { transition-delay: 0.65s; }
.slide.active .anim-d6 { transition-delay: 0.8s; }
.slide.active .anim-d7 { transition-delay: 0.95s; }
.slide.active .anim-d8 { transition-delay: 1.1s; }Shape Entrances
.slide .shape {
opacity: 0;
transition: opacity 1s var(--ease-out-expo), transform 1s var(--ease-out-expo), margin 0.4s ease-out;
}
.slide.active .shape { opacity: 1; }
.slide .shape-enter-left { transform: translateX(-100px) scale(0.7); }
.slide .shape-enter-right { transform: translateX(100px) scale(0.7); }
.slide .shape-enter-top { transform: translateY(-80px) scale(0.7); }
.slide .shape-enter-bottom { transform: translateY(80px) scale(0.7); }
.slide.active .shape-enter-left,
.slide.active .shape-enter-right,
.slide.active .shape-enter-top,
.slide.active .shape-enter-bottom {
transform: translateX(0) translateY(0) scale(1);
}Scale-in (for badges, icons)
.slide .anim-scale {
opacity: 0;
transform: scale(0.5);
transition: opacity 0.5s var(--ease-out-expo), transform 0.5s var(--ease-out-back);
}
.slide.active .anim-scale { opacity: 1; transform: scale(1); }---
Typography
Use clamp() for fluid sizing that works on projectors, laptops, and tablets.
.heading-xl {
font-family: var(--font-heading);
font-weight: 800;
font-size: clamp(56px, 7.5vw, 112px);
line-height: 0.92;
letter-spacing: -0.03em;
}
.heading-lg {
font-family: var(--font-heading);
font-weight: 800;
font-size: clamp(56px, 7.5vw, 112px);
line-height: 0.92;
letter-spacing: -0.03em;
}
.heading-md {
font-family: var(--font-heading);
font-weight: 700;
font-size: clamp(24px, 3vw, 42px);
line-height: 1.2;
}
.italic-accent {
font-family: var(--font-serif);
font-style: italic;
font-weight: 400;
}
.subtitle {
font-family: var(--font-body);
font-size: clamp(14px, 1.5vw, 20px);
font-weight: 500;
letter-spacing: 0.15em;
text-transform: uppercase;
opacity: 0.7;
}
.body-text {
font-family: var(--font-body);
font-size: clamp(16px, 1.8vw, 22px);
line-height: 1.6;
font-weight: 400;
}---
UI Chrome
Progress Bar
.progress-bar {
position: fixed;
bottom: 0; left: 0;
height: 3px;
background: linear-gradient(90deg, var(--primary), var(--secondary));
transition: width 0.5s var(--ease-out-expo);
z-index: 100;
}Slide Counter
.slide-counter {
position: fixed;
bottom: 14px; right: 30px;
font-family: var(--font-body);
font-size: 13px;
font-weight: 600;
color: rgba(255,255,255,0.5);
z-index: 100;
transition: color 0.5s;
letter-spacing: 0.05em;
}
.slide-counter.on-light { color: rgba(45,45,45,0.4); }Nav Hint
.nav-hint {
position: fixed;
bottom: 14px; left: 50%;
transform: translateX(-50%);
font-family: var(--font-body);
font-size: 12px;
font-weight: 500;
color: rgba(255,255,255,0.3);
z-index: 100;
transition: opacity 1.5s, color 0.5s;
letter-spacing: 0.05em;
}
.nav-hint.on-light { color: rgba(45,45,45,0.25); }
.nav-hint.hidden { opacity: 0; }Responsive Breakpoint
@media (max-width: 768px) {
.slide { padding: 40px 32px; }
.slide-footer { left: 32px; right: 32px; bottom: 20px; }
.flow-diagram { flex-direction: column; gap: 12px; }
.flow-arrow { transform: rotate(90deg); }
.slide-llm .slide-content { flex-direction: column; gap: 30px; }
.llm-screenshot { max-width: 100%; }
.glossary-grid--two { grid-template-columns: 1fr; }
.slide-learn { padding-left: 40px !important; }
}---
JavaScript Navigation Engine
Complete template for the IIFE-based slide engine. Adapt bulletSlides array to match which slides have data-bullets.
(function() {
'use strict';
// ===== SLIDE ENGINE =====
const slides = Array.from(document.querySelectorAll('.slide'));
const totalSlides = slides.length;
let currentSlide = 0;
let isTransitioning = false;
let transitionTimeout = null;
// Bullet reveal state — track per-slide
// Find all slides with data-bullets attribute
const bulletSlides = {};
slides.forEach((slide, i) => {
if (slide.dataset.bullets) {
bulletSlides[i] = { index: 0, total: parseInt(slide.dataset.bullets) };
}
});
const progressBar = document.getElementById('progressBar');
const slideCounter = document.getElementById('slideCounter');
const navHint = document.getElementById('navHint');
function updateUI() {
const progress = ((currentSlide) / (totalSlides - 1)) * 100;
progressBar.style.width = progress + '%';
slideCounter.textContent = (currentSlide + 1) + ' / ' + totalSlides;
const theme = slides[currentSlide].dataset.theme;
slideCounter.classList.toggle('on-light', theme === 'light');
navHint.classList.toggle('on-light', theme === 'light');
}
function goToSlide(index) {
if (index < 0 || index >= totalSlides || index === currentSlide || isTransitioning) return;
isTransitioning = true;
clearTimeout(transitionTimeout);
slides[currentSlide].classList.remove('active');
currentSlide = index;
slides[currentSlide].classList.add('active');
// Reset bullet state when entering a bullet slide
if (bulletSlides[currentSlide]) {
resetBullets(currentSlide);
}
updateUI();
transitionTimeout = setTimeout(() => {
isTransitioning = false;
}, 700);
}
function nextSlide() {
// Check if current slide has bullets to reveal
if (bulletSlides[currentSlide]) {
const state = bulletSlides[currentSlide];
const bullets = slides[currentSlide].querySelectorAll('.bullet-list li');
if (state.index < bullets.length) {
bullets[state.index].classList.add('visible');
state.index++;
if (state.index >= bullets.length) {
const hint = slides[currentSlide].querySelector('.bullet-hint');
if (hint) hint.classList.add('hidden');
}
return;
}
}
goToSlide(currentSlide + 1);
}
function prevSlide() {
if (bulletSlides[currentSlide] && bulletSlides[currentSlide].index > 0) {
const state = bulletSlides[currentSlide];
state.index--;
const bullets = slides[currentSlide].querySelectorAll('.bullet-list li');
bullets[state.index].classList.remove('visible');
const hint = slides[currentSlide].querySelector('.bullet-hint');
if (hint) hint.classList.remove('hidden');
return;
}
goToSlide(currentSlide - 1);
}
function resetBullets(slideIndex) {
bulletSlides[slideIndex].index = 0;
const bullets = slides[slideIndex].querySelectorAll('.bullet-list li');
bullets.forEach(b => b.classList.remove('visible'));
const hint = slides[slideIndex].querySelector('.bullet-hint');
if (hint) hint.classList.remove('hidden');
}
// ===== KEYBOARD NAV =====
document.addEventListener('keydown', function(e) {
navHint.classList.add('hidden');
switch (e.key) {
case 'ArrowRight': case 'ArrowDown': case ' ': case 'PageDown':
e.preventDefault(); nextSlide(); break;
case 'ArrowLeft': case 'ArrowUp': case 'PageUp':
e.preventDefault(); prevSlide(); break;
case 'Home':
e.preventDefault(); goToSlide(0); break;
case 'End':
e.preventDefault(); goToSlide(totalSlides - 1); break;
}
});
// ===== CLICK NAV =====
document.addEventListener('click', function(e) {
navHint.classList.add('hidden');
if (e.clientX > window.innerWidth * 0.3) nextSlide();
else prevSlide();
});
// ===== TOUCH/SWIPE NAV =====
let touchStartX = 0, touchStartY = 0;
document.addEventListener('touchstart', function(e) {
touchStartX = e.touches[0].clientX;
touchStartY = e.touches[0].clientY;
}, { passive: true });
document.addEventListener('touchend', function(e) {
navHint.classList.add('hidden');
const dx = e.changedTouches[0].clientX - touchStartX;
const dy = e.changedTouches[0].clientY - touchStartY;
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 50) {
if (dx < 0) nextSlide();
else prevSlide();
}
}, { passive: true });
// ===== MOUSE PARALLAX =====
document.addEventListener('mousemove', function(e) {
const x = (e.clientX / window.innerWidth - 0.5) * 2;
const y = (e.clientY / window.innerHeight - 0.5) * 2;
document.documentElement.style.setProperty('--mx', x);
document.documentElement.style.setProperty('--my', y);
});
// ===== INIT =====
updateUI();
setTimeout(function() { navHint.classList.add('hidden'); }, 5000);
})();HTML for UI Chrome (place after .presentation div)
<div class="progress-bar" id="progressBar"></div>
<div class="slide-counter" id="slideCounter">1 / N</div>
<div class="nav-hint" id="navHint">Use arrow keys or click to navigate</div>Learnings & Design Patterns
Hard-won insights from building presentations with this framework. Reference when making design decisions.
---
Architecture
1. Single file is king — Standalone HTML with embedded CSS, JS, and base64 assets. No build tools, no server, no dependencies. Drop the file anywhere and it works.
2. Absolute positioning for slides — Stack all section.slide elements with position: absolute; inset: 0 and toggle .active. Simpler and more reliable than carousel transforms or scroll-based approaches.
3. CSS variables for everything — Colors, fonts, easing curves, spacing — all in :root. Changing a presentation's entire theme takes 30 seconds of editing custom properties.
4. Transition lockout prevents jank — 700ms isTransitioning flag in JS prevents double-navigation when users click rapidly. Without this, slides stack on top of each other mid-transition.
---
Animation & Polish
5. Easing > duration — cubic-bezier(0.16, 1, 0.3, 1) (expo-out) feels premium on every transition. The curve matters more than the milliseconds. Use ease-out-back sparingly for playful scale-ins.
6. Stagger delays create hierarchy — .anim-d1 through .anim-d8 make content appear to "build" rather than pop. Assign delays in visual reading order: headline first, then subtext, then supporting elements. The eye follows the stagger.
7. Shape decorations sell polish — Floating, blurred, mix-blend-mode: overlay background shapes make slides look designed even with simple content. Use luminosity blend mode for subtlety, overlay for vibrancy.
8. Parallax is cheap polish — 5 lines of JS tracking mouse position to --mx/--my CSS variables, applied to shapes via calc(). Subtle movement that makes slides feel alive.
9. Glassmorphism adds depth — backdrop-filter: blur(28px) + semi-transparent white (rgba(255,255,255,0.07)) + subtle border. Creates visual layers without heavy shadows. Always include -webkit-backdrop-filter for Safari.
---
Navigation
10. Click zones > buttons — Left 30% of screen = back, right 70% = forward. Invisible but intuitive — no UI buttons cluttering slides. Works naturally with presenter remotes too.
11. Bullet reveal is essential — data-bullets attribute + progressive .visible toggling. Dense content slides need progressive disclosure or the audience reads ahead. The JS engine intercepts nextSlide() to reveal bullets before advancing.
12. Touch/swipe needs a threshold — >50px horizontal swipe to trigger, and only if horizontal movement exceeds vertical. Prevents accidental navigation from scrolling gestures.
---
Typography & Layout
13. `clamp()` for typography — clamp(56px, 7.5vw, 112px) works on projectors (1920px), laptops (1440px), and tablets (768px) without media queries. Every text size should use clamp.
14. Tight line-height on display type — line-height: 0.92 on headings makes multi-line titles feel editorial. Body text gets 1.6 for readability.
15. Serif italic as accent — Pairing a bold sans-serif heading font with an italic serif creates instant visual interest. Use font-family: var(--font-serif); font-style: italic; via .italic-accent class.
---
Content
16. Content first, design second — Build the slide outline collaboratively before touching any code. The best animations can't save a confusing narrative arc.
17. One concept per slide — Especially for glossary/definition slides. Large term + concise definition + decorative elements. Resist cramming multiple ideas.
18. Alternate themes for variety — Cycling between .slide--primary, .slide--secondary, and .slide--light prevents monotony. Plan the theme map during the outline step.
---
Export & Delivery
19. Standalone by default — Base64-embed all images (data:image/png;base64,...). The resulting file is large but completely portable. Offer a dev version with external assets for editing.
20. Header/footer chrome — Consistent top bar (tagline + logo) and bottom bar (section name + subtitle) on every slide frames the content professionally. Use position: absolute with pointer-events: none.
Presentation Skill for Claude Code
A Claude Code skill that creates polished single-file HTML/CSS/JS slide deck presentations with animations, keyboard/click/swipe navigation, and progressive bullet reveal.
Installation
1. Copy this folder into your repo's .claude/skills/ directory:
cp -r presentation/ your-repo/.claude/skills/presentation/2. Use it:
/presentation Design to Code Workshopor just:
/presentationClaude will walk you through gathering requirements, building the outline, and generating slides.
What's inside
| File | Purpose |
|---|---|
SKILL.md | Skill definition — the 7-step workflow Claude follows |
framework-reference.md | CSS architecture + JS navigation engine templates |
slide-types.md | HTML templates for 10 slide types |
learnings.md | Design patterns and hard-won insights |
Two modes
- Full generation: Provide content/outline upfront, Claude generates the entire deck in one shot
- Interactive step-by-step: Claude scaffolds the framework, then you build slides one at a time
Slide types
| Type | Use Case |
|---|---|
| Title | Opening slide — large heading, decorative shapes |
| Speaker/Bio | Introduce presenter — avatar, name, role |
| Question | Audience engagement — large centered question |
| Bullet Reveal | Progressive disclosure — points appear on click |
| Tool/Badge Grid | Tools, tech, logos — grid of badge cards |
| Workflow/Flow | Processes — connected boxes with arrows |
| Two-Column | Text + image — split layout |
| Team/Grid | Meet the team — photo grid |
| Glossary | Definitions — large term + explanation |
| Closing/CTA | Final slide — large text, call to action |
Features
- Single standalone HTML file — no build tools, no dependencies
- CSS animations with stagger delays and expo-out easing
- Keyboard navigation (arrows, Space, PgUp/Dn, Home, End)
- Click zones (left 30% = back, right 70% = forward)
- Touch/swipe support
- Progressive bullet reveal
- Mouse parallax on decorative shapes
- Glassmorphism and floating shape decorations
- Progress bar and slide counter
- Responsive at 768px breakpoint
- Base64-embedded assets for true standalone export
Slide Type Templates
HTML templates for each slide type. Load this file when building slides (Step 5).
Adapt class names, colors, content, and shapes to match each presentation's design brief. The patterns here are structural — the visual identity comes from the CSS tokens defined in the framework.
---
1. Title Slide (.slide-title)
Opening slide with large heading, decorative shapes, and glass panel.
<section class="slide slide--primary slide-title active" data-theme="dark">
<!-- Decorative shapes — bleed off edges, luminosity blend -->
<div class="shape shape-pill shape-enter-left" style="top:15%; left:-5%; width:200px;"></div>
<div class="shape shape-sphere shape-enter-right" style="top:-10%; right:-3%; width:180px; height:180px;"></div>
<div class="shape shape-star shape-enter-bottom" style="bottom:-8%; left:20%;"></div>
<!-- Optional glass panel -->
<div class="glass-panel"></div>
<!-- Header chrome -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(255,255,255,0.18); z-index:10; pointer-events:none;">
<span style="font-size:clamp(10px,1vw,14px); font-weight:600; letter-spacing:0.12em; text-transform:uppercase; opacity:0.5;">Tagline</span>
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em;">Logo</span>
</div>
<div class="slide-content" style="z-index:4; position:relative;">
<div class="title-main anim anim-d1">First Line</div>
<div class="title-main anim anim-d2">Second <span class="italic-accent">Line</span></div>
</div>
<div class="slide-footer" style="z-index:4;">
<span class="anim anim-d3">Presenter Name @ Role</span>
</div>
</section>CSS (slide-specific):
.slide-title {
justify-content: center !important;
align-items: flex-start !important;
padding-left: 8vw !important;
padding-right: 8vw !important;
}
.slide-title .slide-content {
text-align: left; z-index: 3; position: relative;
display: flex; flex-direction: column; align-items: flex-start; gap: 0;
}
.slide-title .title-main {
font-family: var(--font-heading); font-weight: 800;
font-size: clamp(56px, 7.5vw, 112px); line-height: 0.92; letter-spacing: -0.03em;
}---
2. Speaker/Bio Slide (.slide-speaker)
Introduce the presenter with avatar, name, role, and glass card backdrop.
<section class="slide slide--primary slide-speaker" data-theme="dark">
<!-- Shapes -->
<div class="shape shape-sphere shape-enter-left" style="top:-18%; left:-10%; width:200px; height:200px;"></div>
<div class="shape shape-pill shape-enter-right" style="bottom:-10%; right:-6%;"></div>
<!-- Glass card -->
<div class="glass-panel"></div>
<div class="speaker-layout">
<div class="avatar-ring anim anim-d1 anim-scale">
<img src="avatar.jpg" alt="Name">
</div>
<div class="speaker-subtitle anim anim-d2">Tagline or motto</div>
<div class="speaker-name anim anim-d3">Full Name</div>
<div class="speaker-title-text anim anim-d4">title & company</div>
</div>
<div class="slide-footer" style="z-index:3;">
<span>Presentation Title</span>
<span class="italic-accent">subtitle</span>
</div>
</section>CSS (slide-specific):
.slide-speaker .speaker-layout {
display: flex; flex-direction: column; align-items: center;
gap: 28px; z-index: 3; position: relative;
}
.avatar-ring {
width: clamp(160px, 18vw, 240px); height: clamp(160px, 18vw, 240px);
border-radius: 50%; border: 3px solid rgba(255,255,255,0.3);
overflow: hidden;
background: linear-gradient(135deg, rgba(255,255,255,0.15), rgba(255,255,255,0.05));
display: flex; align-items: center; justify-content: center;
}
.avatar-ring img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.speaker-name {
font-family: var(--font-heading); font-weight: 700;
font-size: clamp(20px, 2.5vw, 32px); text-align: center;
}
.speaker-title-text {
font-size: clamp(13px, 1.2vw, 16px); opacity: 0.6;
font-weight: 500; letter-spacing: 0.1em; text-transform: lowercase;
}
.speaker-subtitle {
font-family: var(--font-serif); font-style: italic;
font-size: clamp(18px, 2.2vw, 30px); opacity: 0.7;
}---
3. Question Slide (.slide-familiar)
Large centered question for audience engagement.
<section class="slide slide--primary slide-familiar" data-theme="dark" style="justify-content:center; align-items:flex-start; padding:0 8vw;">
<!-- Header -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(255,255,255,0.18); z-index:10; pointer-events:none;">
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em;">Logo</span>
</div>
<!-- Shapes -->
<div class="shape shape-sphere shape-enter-left" style="top:-2%; right:22%; width:18vw; max-width:240px;"></div>
<div class="slide-content" style="flex-direction:column; align-items:flex-start; text-align:left; gap:0;">
<div class="heading-xl anim anim-d1">Does This</div>
<div class="heading-xl anim anim-d2"><span class="italic-accent">Sound Familiar?</span></div>
</div>
<div class="slide-footer">
<span>Presentation Title</span>
<span>Subtitle</span>
</div>
</section>---
4. Bullet Reveal Slide (.slide-learn)
Progressive disclosure — bullets appear one by one on click/keypress.
<section class="slide slide--secondary slide-learn" data-theme="dark" data-bullets="4" style="justify-content:center !important; align-items:flex-start !important; padding:0 8vw !important;">
<!-- Header -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(255,255,255,0.2); z-index:10; pointer-events:none;">
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em;">Logo</span>
</div>
<!-- Large decorative shape -->
<div class="shape shape-star shape-enter-right" style="position:absolute; top:50%; right:-18%; transform:translateY(-50%); width:500px; height:500px; opacity:0.75; z-index:1;"></div>
<div class="slide-content" style="flex-direction:column; align-items:flex-start; justify-content:center; gap:5vh; z-index:3;">
<div>
<div class="heading-lg anim anim-d1">What You’ll</div>
<div class="heading-lg anim anim-d2"><span class="italic-accent">Learn Today</span></div>
</div>
<ul class="bullet-list">
<li data-bullet="1">First point to reveal</li>
<li data-bullet="2">Second point to reveal</li>
<li data-bullet="3">Third point to reveal</li>
<li data-bullet="4">Fourth point to reveal</li>
</ul>
<div class="bullet-hint">Press → to reveal next point</div>
</div>
<div class="slide-footer">
<span>Presentation Title</span>
<span>Subtitle</span>
</div>
</section>Key: data-bullets="4" on the section tells the JS engine how many bullets to reveal before advancing. Each <li> starts hidden and gets .visible class on click.
CSS (slide-specific):
.slide-learn { align-items: flex-start !important; padding-left: 12% !important; }
.slide-learn .slide-content {
z-index: 1; display: flex; flex-direction: column; gap: 12px; max-width: 750px;
}
.bullet-list {
list-style: none; display: flex; flex-direction: column; gap: 18px; margin-top: 24px;
}
.bullet-list li {
font-family: var(--font-body); font-size: clamp(18px, 2vw, 26px); font-weight: 500;
line-height: 1.4; padding-left: 28px; position: relative;
opacity: 0; transform: translateY(16px);
transition: opacity 0.5s var(--ease-out-expo), transform 0.5s var(--ease-out-expo);
}
.bullet-list li.visible { opacity: 1; transform: translateY(0); }
.bullet-list li::before {
content: ''; position: absolute; left: 0; top: 8px;
width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,0.6);
}
.bullet-hint {
font-size: 14px; opacity: 0.4; font-weight: 500; margin-top: 20px; transition: opacity 0.3s;
}
.bullet-hint.hidden { opacity: 0; }---
5. Tool/Badge Grid Slide (.slide-setup)
Grid of tool badges with icons.
<section class="slide slide--light slide-setup" data-theme="light" style="justify-content:center; align-items:flex-start; padding:0 8vw;">
<!-- Header -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(28,28,28,0.1); z-index:10; pointer-events:none;">
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em; color:var(--dark);">Logo</span>
</div>
<div class="slide-content" style="flex-direction:column; align-items:flex-start; gap:5vh; padding-top:4vh;">
<div>
<div class="heading-lg anim anim-d1" style="color:var(--dark);">Setting Up</div>
<div class="heading-lg anim anim-d2" style="color:var(--dark);">Your <span class="italic-accent">Environment</span></div>
</div>
<div class="tool-grid" style="justify-content:flex-start;">
<div class="tool-badge anim-scale anim-d3">
<div class="badge-icon" style="background:#24292e;">G</div>
Tool Name
</div>
<div class="tool-badge anim-scale anim-d4">
<div class="badge-icon" style="background:#000;">C</div>
Another Tool
</div>
<!-- Add more badges as needed -->
</div>
</div>
<div class="slide-footer">
<span>Presentation Title</span>
<span>Subtitle</span>
</div>
</section>CSS (slide-specific):
.tool-grid { display: flex; flex-wrap: wrap; gap: 16px; justify-content: center; margin-top: 16px; }
.tool-badge {
display: flex; align-items: center; gap: 10px; padding: 14px 28px;
border-radius: 50px; font-family: var(--font-heading); font-weight: 700;
font-size: clamp(14px, 1.4vw, 18px); letter-spacing: 0.04em; text-transform: uppercase;
background: var(--white); color: var(--dark); box-shadow: 0 4px 20px rgba(0,0,0,0.06);
}
.tool-badge .badge-icon {
width: 28px; height: 28px; border-radius: 6px;
display: flex; align-items: center; justify-content: center;
font-size: 14px; font-weight: 800; color: white;
}---
6. Workflow/Flow Slide (.slide-flow)
Connected process steps with arrows.
<section class="slide slide--primary slide-flow" data-theme="dark">
<!-- Shapes -->
<div class="shape shape-sphere shape-enter-left" style="bottom:-8%; left:-4%; width:200px; height:200px; opacity:0.45;"></div>
<div class="slide-content">
<div class="heading-lg anim anim-d1" style="text-align:center;">How They Work <span class="italic-accent">Together</span></div>
<div class="flow-diagram">
<div class="flow-step anim anim-d2">
<div class="flow-box">Step 1</div>
<div class="flow-label">description</div>
</div>
<div class="flow-arrow anim anim-d3">→</div>
<div class="flow-step anim anim-d3">
<div class="flow-box">Step 2</div>
<div class="flow-label">description</div>
</div>
<div class="flow-arrow anim anim-d4">→</div>
<div class="flow-step anim anim-d4">
<div class="flow-box">Step 3</div>
<div class="flow-label">description</div>
</div>
</div>
</div>
<div class="slide-footer">
<span>Presentation Title</span>
<span class="italic-accent">subtitle</span>
</div>
</section>CSS (slide-specific):
.slide-flow .slide-content {
z-index: 1; width: 100%; max-width: 1000px;
display: flex; flex-direction: column; align-items: center; gap: 40px;
}
.flow-diagram { display: flex; align-items: center; gap: 0; width: 100%; justify-content: center; }
.flow-step { display: flex; flex-direction: column; align-items: center; gap: 10px; min-width: 120px; }
.flow-box {
padding: 16px 24px; border-radius: 14px;
background: rgba(255,255,255,0.15); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.2);
font-family: var(--font-heading); font-weight: 700; font-size: clamp(13px, 1.4vw, 18px);
text-align: center; white-space: nowrap;
}
.flow-label { font-size: clamp(11px, 1vw, 14px); opacity: 0.5; font-weight: 500; text-transform: lowercase; }
.flow-arrow { font-size: 24px; opacity: 0.4; margin: 0 8px; flex-shrink: 0; }---
7. Two-Column Slide (.slide-llm)
Text on left, image/screenshot on right.
<section class="slide slide--light slide-llm" data-theme="light">
<!-- Header -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(28,28,28,0.1); z-index:10; pointer-events:none;">
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em; color:var(--dark);">Logo</span>
</div>
<div class="slide-content">
<div class="llm-text">
<div class="heading-lg anim anim-d1" style="color:var(--dark);">First Line</div>
<div class="heading-lg anim anim-d2" style="color:var(--dark);"><span class="italic-accent">Second Line</span></div>
<div style="display:flex; flex-direction:column; gap:10px; margin-top:20px;">
<div class="open-source-badge anim-scale anim-d3">Badge Text</div>
</div>
</div>
<div class="llm-screenshot anim anim-d3">
<img src="screenshot.png" alt="Description">
</div>
</div>
<div class="slide-footer">
<span>Presentation Title</span>
<span>Subtitle</span>
</div>
</section>CSS (slide-specific):
.slide-llm .slide-content {
z-index: 1; display: flex; align-items: center; gap: 60px; width: 100%; max-width: 1100px;
}
.llm-text { flex: 1; display: flex; flex-direction: column; gap: 16px; }
.llm-screenshot {
flex: 1; max-width: 480px; border-radius: 16px; overflow: hidden;
box-shadow: 0 16px 60px rgba(0,0,0,0.12); background: var(--white);
border: 1px solid rgba(0,0,0,0.06);
}
.llm-screenshot img { width: 100%; display: block; }
.open-source-badge {
display: inline-block; padding: 6px 18px; border-radius: 20px;
background: var(--secondary); color: var(--white);
font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
width: fit-content;
}---
8. Team/Grid Slide (.slide-speakers)
Photo grid with names and roles for multiple people.
<section class="slide slide--primary slide-speakers" data-theme="dark">
<!-- Header chrome -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(255,255,255,0.18); z-index:10; pointer-events:none;">
<span style="font-size:clamp(10px,1vw,14px); font-weight:600; letter-spacing:0.12em; text-transform:uppercase; opacity:0.5;">Tagline</span>
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em;">Logo</span>
</div>
<!-- Glass backdrop -->
<div class="speakers-glass"></div>
<div class="speakers-layout">
<div class="speakers-intro anim anim-d1">Meet the team</div>
<div class="speakers-row">
<div class="speaker-card anim anim-d2">
<div class="avatar-ring"><img src="person1.jpg" alt="Name"></div>
<div class="speaker-name">Full Name</div>
<div class="speaker-handle">@handle · role</div>
</div>
<div class="speaker-card anim anim-d3">
<div class="avatar-ring"><img src="person2.jpg" alt="Name"></div>
<div class="speaker-name">Full Name</div>
<div class="speaker-handle">@handle · role</div>
</div>
<div class="speaker-card anim anim-d4">
<div class="avatar-ring"><img src="person3.jpg" alt="Name"></div>
<div class="speaker-name">Full Name</div>
<div class="speaker-handle">@handle · role</div>
</div>
</div>
</div>
<div class="slide-footer" style="z-index:3;">
<span>Presentation Title</span>
<span class="italic-accent">subtitle</span>
</div>
</section>CSS (slide-specific):
.slide-speakers { justify-content: center !important; align-items: center !important; }
.speakers-glass {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
width: 88%; height: 80%;
background: rgba(255,255,255,0.06); backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px);
border-radius: 40px; border: 1px solid rgba(255,255,255,0.15); z-index: 2; pointer-events: none;
}
.speakers-layout {
display: flex; flex-direction: column; align-items: center; justify-content: center;
gap: 0; z-index: 3; position: relative;
}
.speakers-row {
display: flex; align-items: center; justify-content: center;
gap: clamp(40px, 6vw, 96px);
}
.speaker-card {
display: flex; flex-direction: column; align-items: center;
gap: clamp(10px, 1.4vh, 18px); text-align: center;
}
.speaker-card .avatar-ring { width: clamp(110px, 12vw, 170px); height: clamp(110px, 12vw, 170px); }
.speaker-card .speaker-name { font-size: clamp(14px, 1.5vw, 22px); }
.speaker-handle {
font-family: var(--font-body); font-size: clamp(10px, 0.9vw, 13px);
font-weight: 500; letter-spacing: 0.08em; opacity: 0.45;
}
.speakers-intro {
font-family: var(--font-serif); font-style: italic;
font-size: clamp(16px, 2vw, 28px); opacity: 0.65;
margin-bottom: clamp(20px, 3.5vh, 44px); text-align: center;
}---
9. Glossary/Definition Slide (.slide-gloss)
Large term with definition — one concept per slide.
<section class="slide slide--light slide-gloss" data-theme="light">
<!-- Header chrome -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(28,28,28,0.1); z-index:10; pointer-events:none;">
<span style="font-size:clamp(10px,1vw,14px); font-weight:600; letter-spacing:0.12em; text-transform:uppercase; opacity:0.5; color:var(--dark);">Tagline</span>
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em; color:var(--dark);">Logo</span>
</div>
<div class="slide-content" style="flex-direction:column; align-items:flex-start; gap:0; z-index:3;">
<p class="gloss-eyebrow anim anim-d1">Glossary</p>
<h2 class="gloss-term anim anim-d2">Term<br><em>Name</em></h2>
<div class="gloss-rule anim anim-d3"></div>
<p class="gloss-def anim anim-d4"><span class="gloss-arrow">→</span>Definition text goes here explaining the concept clearly.</p>
</div>
<div class="slide-footer" style="z-index:4;">
<span class="anim anim-d3">Presenter Name @ Role</span>
</div>
</section>CSS (slide-specific):
.slide-gloss {
align-items: flex-start !important; justify-content: center !important; padding: 0 8vw !important;
}
.slide-gloss .slide-content {
z-index: 3; display: flex; flex-direction: column; align-items: flex-start; gap: 0; max-width: 900px;
}
.gloss-eyebrow {
font-family: var(--font-body); font-size: clamp(11px, 1vw, 14px); font-weight: 700;
letter-spacing: 0.22em; text-transform: uppercase; opacity: 0.4; margin-bottom: 2.5vh;
}
.gloss-term {
font-family: var(--font-heading); font-weight: 800;
font-size: clamp(60px, 8.5vw, 130px); line-height: 0.88; letter-spacing: -0.04em; margin-bottom: 4vh;
}
.gloss-term em {
font-family: var(--font-serif); font-style: italic; font-weight: 400; letter-spacing: -0.02em;
}
.gloss-rule {
width: clamp(200px, 35vw, 560px); height: 1px;
background: currentColor; opacity: 0.18; margin-bottom: 4vh;
}
.gloss-def {
font-family: var(--font-body); font-size: clamp(17px, 1.9vw, 27px); font-weight: 500;
line-height: 1.6; max-width: 680px; opacity: 0.85;
}
.gloss-arrow { display: inline-block; margin-right: 6px; opacity: 0.5; }Note: Glossary slides work well alternating between theme variants (.slide--primary, .slide--secondary, .slide--light) for visual variety.
---
10. Closing/CTA Slide (.slide-closing)
Final slide with large text and call to action.
<section class="slide slide--primary slide-closing" data-theme="dark">
<!-- Shapes — dense layering for dramatic finish -->
<div class="shape shape-pill shape-enter-left" style="top:-16%; left:-8%; width:300px; opacity:0.3;"></div>
<div class="shape shape-star shape-enter-right" style="top:-10%; right:-7%; width:250px; height:250px; opacity:0.55; z-index:3;"></div>
<div class="shape shape-sphere shape-enter-bottom" style="bottom:-12%; left:-5%; width:280px; height:280px; opacity:0.3;"></div>
<!-- Glass card -->
<div class="glass-panel"></div>
<!-- Header chrome -->
<div style="position:absolute; top:0; left:0; right:0; padding:2vh 4vw; display:flex; justify-content:space-between; align-items:center; border-top:1px solid rgba(255,255,255,0.18); z-index:10; pointer-events:none;">
<span style="font-size:clamp(10px,1vw,14px); font-weight:600; letter-spacing:0.12em; text-transform:uppercase; opacity:0.5;">Tagline</span>
<span style="font-size:clamp(14px,1.3vw,20px); font-weight:800; letter-spacing:-0.02em;">Logo</span>
</div>
<div class="slide-content" style="flex-direction:column; align-items:center; text-align:center; gap:0; z-index:4; position:relative;">
<div class="title-main anim anim-d1">Thank</div>
<div class="title-main anim anim-d2"><span class="italic-accent">You!</span></div>
</div>
<div class="slide-footer" style="z-index:4;">
<span class="anim anim-d3">Presenter Name @ Role</span>
</div>
</section>CSS (slide-specific):
.slide-closing .slide-content {
text-align: center; z-index: 4; position: relative;
display: flex; flex-direction: column; align-items: center; gap: 0;
}
.slide-closing .title-main {
font-family: var(--font-heading); font-weight: 800;
font-size: clamp(60px, 8vw, 120px); line-height: 0.9; letter-spacing: -0.03em;
}