SlideNerds

Slide definition language

Every SlideNerds deck is a Next.js page. Slides are HTML sections with data attributes. No proprietary format, no DSL. Just React.

Structure

A deck is a single page component that returns sections. Each section with data-slide becomes a slide.

export default function Home() {
  return (
    <main>
      <section data-slide="">
        <h1>Title slide</h1>
      </section>

      <section data-slide="">
        <h2>Second slide</h2>
        <p>Content goes here</p>
      </section>
    </main>
  )
}

Data attributes

AttributeElementPurpose
data-slide<section>Marks an element as a slide. Required on every slide.
data-stepAny childProgressive reveal. Hidden until the presenter advances. Use for bullet points, images, or any content.
data-notesAny childSpeaker notes. Hidden during presentation, visible in presenter mode (press P).
data-magic-idAny childShared identity for Magic Move. Elements with the same ID on consecutive slides animate between positions.

Progressive reveal (data-step)

Add data-step to any element to hide it until the presenter presses the right arrow or space. Steps reveal in DOM order. Pair with an animation class for visual effect.

<section data-slide="">
  <h2>Three reasons</h2>
  <ul>
    <li data-step="" className="step-fade">First reason</li>
    <li data-step="" className="step-fade">Second reason</li>
    <li data-step="" className="step-fade">Third reason</li>
  </ul>
</section>

Entrance animations (step-*)

Apply to data-step elements to control how they appear when revealed.

Fades

ClassEffect
step-fadeOpacity 0 to 1
step-fade-slowSlow fade in
step-dissolveDissolve in

Slides and flies

ClassEffect
step-move-upSlide up + fade
step-move-downSlide down + fade
step-move-leftSlide left + fade
step-move-rightSlide right + fade
step-fly-in-leftFly in from far left
step-fly-in-rightFly in from far right
step-fly-in-topFly in from top
step-fly-in-bottomFly in from bottom
step-float-upFloat up gently
step-float-downFloat down gently
step-slide-in-leftSlide in from left
step-slide-in-rightSlide in from right
step-glide-upGlide up
step-glide-downGlide down
step-peek-leftPeek in from left
step-peek-rightPeek in from right

Scales and zooms

ClassEffect
step-scale-inScale 0.92 to 1 + fade
step-scale-upScale up from small
step-scale-downScale down from large
step-zoom-inZoom in from tiny
step-zoom-in-rotateZoom in with rotation
step-growGrow from nothing

Pops and bounces

ClassEffect
step-popScale pop with spring overshoot
step-bounceBounce in
step-bounce-leftBounce in from left
step-bounce-rightBounce in from right
step-elasticElastic spring entrance
step-dropDrop in from above
step-riseRise up from below
step-swing-inSwing in with rotation

Spins and flips

ClassEffect
step-spin-inSpin in with rotation
step-spin-in-slowSlow spin in
step-flip-xFlip on X axis
step-flip-yFlip on Y axis
step-rotate-inRotate in from angle

Wipes and reveals

ClassEffect
step-wipe-rightClip-path wipe right
step-wipe-leftClip-path wipe left
step-wipe-upClip-path wipe up
step-wipe-downClip-path wipe down
step-irisIris circle reveal
step-diamond-revealDiamond shape reveal
step-split-horizontalSplit open horizontally
step-split-verticalSplit open vertically

Filters

ClassEffect
step-blur-inBlur to sharp
step-unblurUnblur reveal
step-brightnessBrighten in
step-saturateSaturate colors in

Text

ClassEffect
step-typewriterTypewriter character reveal
step-text-revealText clip reveal
step-letter-spreadLetters spread from center

Exit animations (exit-*)

Apply to data-exit-step elements. They animate out before the slide transitions.

ClassEffect
exit-fadeFade out
exit-move-upSlide up + fade out
exit-move-downSlide down + fade out
exit-move-leftSlide left + fade out
exit-move-rightSlide right + fade out
exit-fly-out-leftFly out to far left
exit-fly-out-rightFly out to far right
exit-fly-out-topFly out to top
exit-fly-out-bottomFly out to bottom
exit-scale-downScale down + fade out
exit-scale-upScale up + fade out
exit-zoom-outZoom out to nothing
exit-spin-outSpin out with rotation
exit-flip-xFlip away on X axis
exit-flip-yFlip away on Y axis
exit-wipe-leftWipe away left
exit-wipe-rightWipe away right
exit-wipe-upWipe away up
exit-wipe-downWipe away down
exit-irisIris circle close
exit-blurBlur out
exit-drop-offDrop off screen
exit-bounce-offBounce off screen
exit-popPop away
exit-shrink-rotateShrink and rotate away
exit-dissolveDissolve out

Emphasis animations (emphasis-*)

Apply to data-step elements. Triggered on second click to draw attention to a visible element.

ClassEffect
emphasis-pulseScale pulse
emphasis-bounceBounce in place
emphasis-shakeHorizontal shake
emphasis-wobbleWobble rotation
emphasis-jiggleQuick jiggle
emphasis-rubber-bandRubber band stretch
emphasis-swingPendulum swing
emphasis-tadaAttention-getting tada
emphasis-heartbeatHeartbeat pulse
emphasis-flashFlash opacity
emphasis-spinFull spin
emphasis-floatFloat up and down
emphasis-glowGlow effect
emphasis-color-pulseColor shift pulse
emphasis-teeterTeeter back and forth
emphasis-flickerQuick flicker
emphasis-growGrow slightly
emphasis-shrinkShrink slightly

Auto-build animations (auto-*)

Animate elements automatically when a slide becomes active. No data-step needed. Stagger with animationDelay.

ClassEffect
auto-fadeFade in on slide enter
auto-slide-upSlide up + fade
auto-slide-downSlide down + fade
auto-slide-leftSlide left + fade
auto-slide-rightSlide right + fade
auto-popScale pop
auto-scale-inScale in
auto-zoom-inZoom in
auto-wipe-rightWipe right
auto-wipe-leftWipe left
auto-blur-inBlur to sharp
auto-fly-in-leftFly in from left
auto-fly-in-rightFly in from right
auto-bounceBounce in
auto-spin-inSpin in
auto-flip-xFlip on X axis
<section data-slide="">
  <h2>Our team</h2>
  <div className="auto-fade" style={{ animationDelay: '0.2s' }}>
    Card 1
  </div>
  <div className="auto-fade" style={{ animationDelay: '0.4s' }}>
    Card 2
  </div>
</section>

Slide transitions (data-transition)

Set the data-transition attribute on a slide to control how it transitions to/from the next slide.

ValueEffect
fadeCross-fade (default)
dissolveDissolve blend
push-leftPush left
push-rightPush right
push-upPush up
push-downPush down
slide-leftSlide left
slide-rightSlide right
cover-leftCover from right
cover-rightCover from left
cover-upCover from bottom
cover-downCover from top
uncover-leftUncover to left
uncover-rightUncover to right
uncover-upUncover to top
uncover-downUncover to bottom
zoom-inZoom in
zoom-outZoom out
flip-x3D flip on X axis
flip-y3D flip on Y axis
cube-left3D cube rotate left
cube-right3D cube rotate right
irisIris circle reveal
split-horizontalSplit open horizontally
split-verticalSplit open vertically
morphMorph blend
<section data-slide="" data-transition="cube-left">
  <h1>This slide uses a 3D cube transition</h1>
</section>

Magic Move

Give elements the same data-magic-id on consecutive slides. The runtime animates position and scale between them automatically.

{/* Slide 1: revenue number is large and centered */}
<section data-slide="">
  <div data-magic-id="revenue" className="text-6xl font-bold">
    $4.2M
  </div>
</section>

{/* Slide 2: same element, now small and top-left */}
<section data-slide="">
  <div data-magic-id="revenue" className="text-xl">
    $4.2M
  </div>
  <p>Here is how we got there.</p>
</section>

Speaker notes

Add data-notes to any element inside a slide. The content is hidden during presentation and shown in the presenter view (press P).

<section data-slide="">
  <h2>Revenue growth</h2>
  <p>Up 18% quarter over quarter</p>
  <div data-notes="">
    Mention the enterprise deal pipeline.
    Ask if anyone has questions about methodology.
  </div>
</section>

Brand configuration

The brand.config.ts file at the root of your project defines colors, fonts, and spacing. The layout injects these as CSS custom properties. One file change rebrands the entire deck.

// brand.config.ts
export default {
  colors: {
    primary: '#0d0d0f',     // Section dividers, dark surfaces
    accent: '#f59e0b',      // Highlights, stats, chart fills
    background: '#111114',  // Slide canvas
    surface: '#1a1a1f',     // Card backgrounds
    text: '#e8e6e3',        // Body text and headings
  },
  fonts: {
    heading: '"Inter", system-ui, sans-serif',
    body: '"Inter", system-ui, sans-serif',
    mono: '"JetBrains Mono", ui-monospace, monospace',
  },
  spacing: {
    slide: '5rem',     // Outer slide padding
    section: '2rem',   // Gap between sections
    element: '1rem',   // Gap between elements
  },
}
CSS variableSourceUsage
--color-primarycolors.primarySection dividers, darkest surfaces
--color-accentcolors.accentHighlights, stats, shape strokes, chart fills
--color-backgroundcolors.backgroundSlide canvas background
--color-surfacecolors.surfaceCard backgrounds
--color-textcolors.textPrimary text color
--slide-paddingspacing.slideOuter slide padding
--font-headingfonts.headingHeading font stack
--font-bodyfonts.bodyBody text font stack
--font-monofonts.monoMonospace font stack

Utility classes

ClassPurpose
section-labelSmall uppercase accent-colored label above a heading
card-surfaceRounded container with surface background and border
accent-line40x3px decorative accent line
stat-glowText shadow glow for large numbers
bg-mesh-warmSubtle warm radial gradient background
bg-mesh-coolSubtle cool radial gradient background
bg-sectionLinear gradient for section dividers
slide-tableTable with uppercase headers and border styling
timeline-trackHorizontal connector line for timelines
timeline-dotAccent circle with glow for timeline nodes
sr-onlyVisually hidden, accessible to screen readers

Keyboard controls

KeyAction
Space / Right arrowNext step or slide
Left arrow / BackspacePrevious step or slide
PPresenter mode (notes + timer)
LLight Table (slide overview)
FFullscreen
?Show keyboard shortcuts
EscapeExit Light Table or fullscreen

Shape system

18 SVG shapes available via the SlideShape component.

import { SlideShape } from '@strategicnerds/slide-nerds'

<SlideShape
  shape="hexagon"
  size={120}
  fill="var(--color-surface)"
  stroke="var(--color-accent)"
  strokeWidth={1.5}
>
  <p>Label</p>
</SlideShape>

Available shapes: circle, square, rounded-square, triangle, diamond, pentagon, hexagon, octagon, star, plus, cloud, arrow-right, arrow-left, chevron-right, pill.

Embedding React components

Slides are React components. Import and render anything -- charts, interactive demos, live data.

import { PricingCalculator } from '../components/PricingCalculator'

<section data-slide="">
  <h2>Interactive demo</h2>
  <PricingCalculator initialPlan="pro" />
  <div data-notes="">
    Let the audience interact with the calculator.
    Switch to cached data if the API is down.
  </div>
</section>

Live components

Five components for real-time audience interaction. Require a hosted deck on slidenerds.com with an active live session.

import {
  LivePoll,
  LiveReactions,
  LiveQA,
  LiveAudienceCount,
  LiveWordCloud,
} from '@strategicnerds/slide-nerds'

<section data-slide="">
  <LivePoll
    question="What matters most?"
    options={['Speed', 'Reliability', 'Cost']}
  />
</section>

<section data-slide="">
  <LiveQA />
  <LiveReactions />
</section>

<section data-slide="">
  <LiveWordCloud prompt="One word for your experience" />
  <LiveAudienceCount />
</section>