Skip to content

Repository files navigation

Gabe Presentations Styles

A lightweight, modular slide system to build beautiful presentations fast using React, Vite, Tailwind v4, and Framer Motion — branded as “Gabe Presentations Styles”. Each presentation is a component; each slide is a tiny TSX file for maximum reuse and composability.

Stack

  • React 18 + Vite 5
  • Tailwind CSS v4 (via @tailwindcss/vite)
  • TypeScript
  • Framer Motion (animations)
  • Bun (package manager & scripts)

Quickstart

  • Install deps: bun install
  • Dev server: bun dev then open http://localhost:5173
  • Build: bun run build (outputs to dist/)
  • Preview build: bun run preview
  • Typecheck: bun run typecheck

Project layout

src/
  App.tsx                    # routes
  routes/
    PresentationList.tsx     # list of decks
    DeckRunner.tsx           # renders a selected deck
  shared/
    deck/                    # Deck, Slide, controls, navigation
    motion/                  # animation presets
  presentations/
    index.ts                 # registry of all presentations
    sample/                  # example deck
    storypoints/             # Story Points deck (slides as TSX files)
      slides/
        Title.tsx
        HookJeffries.tsx
        ComplexityTrap.tsx
        Weaponization.tsx
        AccuracyVsCounting.tsx
        Goodhart.tsx
        ValueOverEffort.tsx
        FocusPrioritizationImpact.tsx
        WhatToUseInstead.tsx
        MiniExample.tsx
        CloseSlide.tsx
        Citations.tsx

Create a new presentation

  1. Create a deck component under src/presentations/<your-deck>/slides/ with one TSX per slide.
  2. Export a router component that switches on slide.id.
  3. Register it in src/presentations/index.ts with an id, title, and slides array.
  4. Navigate to /p/<id> or click from the homepage.

Authoring slides

  • Keep slides small and focused. Compose visuals using Tailwind and Framer Motion.
  • Use the identity gradient with bg-gradient-to-r from-accent to-accent2 bg-clip-text text-transparent.
  • Built-in transitions: 'fade' | 'slide' | 'up' | 'scale'. See shared/motion/presets.ts.
  • Keyboard: and Space. Mouse wheel supported.

Tailwind v4 notes

  • Config is plugin-based; no tailwind.config.js required. Tokens are defined in src/styles/index.css under @theme.
  • Add global styles/tokens in src/styles/index.css.

GitHub

GitHub Actions (CI)

  • .github/workflows/ci.yml runs install, typecheck, and build on pushes and PRs to main using Bun.

Recommended Git commands

# First time
git init
git add .
git commit -m "chore: bootstrap presentations app"

# Create the main branch (if needed)
git branch -M main

# Set the remote and push
git remote add origin git@github.com:Nepomuceno/presentations.git
git push -u origin main

Keeping Private Decks Out of Public Builds

If you don’t want to commit or publish some presentations:

  • Create src/presentations/private.ts locally (this file is gitignored).
  • Export an array of PresentationEntry with your private decks.
  • Public builds (including GitHub Pages) automatically use the empty stub src/presentations/private.example.ts.

Example:

// src/presentations/private.ts (local only)
import type { PresentationEntry } from '../types'
import MyPrivateDeck from './my-private/MyPrivateDeck'

const privatePresentations: PresentationEntry[] = [
  {
    id: 'my-private',
    title: 'Confidential Deck',
    subtitle: 'Internal only',
    slides: [{ id: 'title', transition: 'fade' }],
    component: MyPrivateDeck,
  },
]

export default privatePresentations

To include private decks when developing or building locally, set:

VITE_INCLUDE_PRIVATE=true bun run dev
VITE_INCLUDE_PRIVATE=true bun run build

CI (GitHub Pages) runs without this flag, so only public decks are deployed.

Password‑Protect a Deck (Basic)

This is a light, client‑side gate. The password/hash ships in the bundle, so use only as a deterrent (not true security).

  1. Generate a SHA‑256 hash of your password:
node -e "console.log(require('crypto').createHash('sha256').update('mySecret').digest('hex'))"
  1. Add the hash to your deck entry (either public or private):
// e.g., in src/presentations/public.ts or your private.ts
{
  id: 'vantage',
  title: 'Vantage – Opportunity Brief',
  subtitle: 'From Demonstrator to Greenfield Product',
  passwordHash: 'e0b1...<your sha256 hex>...',
  slides: [ /* ... */ ],
  component: VantageDeck,
}
  1. Run the app and open /p/vantage. You’ll see a password prompt. Successful unlock persists in localStorage per deck.

Notes:

  • Hash comparison happens client‑side using WebCrypto.
  • Anyone can still extract the hash from the JS and brute force it offline. For real protection, front the site with Cloudflare Access or host behind auth.

Add a Private Presentation (Step-by-Step)

  • Create your deck under src/presentations/<your-private-id>/ with slides just like public decks.
  • Create src/presentations/private.ts (gitignored) and export your entries.
  • Run locally with VITE_INCLUDE_PRIVATE=true bun run dev.
  • Open the deck at /p/<your-private-id>.
  • Optional: build a local bundle that includes private decks with VITE_INCLUDE_PRIVATE=true bun run build (do not upload this to public hosting).

Troubleshooting:

  • If you see “Failed to resolve import 'presentations-private'”, restart the dev server after creating src/presentations/private.ts so Vite picks up the alias.

Basic Protection Options

GitHub Pages does not support authentication. For simple gating beyond obscurity:

  • Cloudflare Access in front of your Pages domain (SSO / one-time PIN; free tier available).
  • Host on Netlify/Vercel and enable site-wide password (requires paid plan).
  • Serve from your own server behind HTTP Basic Auth.

Client-side password prompts are possible but weak: the password and content ship in the JS bundle. Use only as a light deterrent.

Use a Private Git Repo for Decks

If you want private decks in a separate repo:

  1. Add the private repo as a Git submodule:
git submodule add git@github.com:<you>/<private-decks>.git src/presentations/private-repo
  1. In your local src/presentations/private.ts (gitignored), import from that repo and re-export entries:
import type { PresentationEntry } from '../types'
import MyPrivateDeck from './private-repo/my-deck/MyPrivateDeck'

const privatePresentations: PresentationEntry[] = [
  { id: 'my-private', title: 'Private', slides: [ { id: 'title' } ], component: MyPrivateDeck },
]

export default privatePresentations
  1. Work locally with VITE_INCLUDE_PRIVATE=true bun run dev. CI will skip them and deploy only public decks.

License

MIT — see LICENSE.

About

Presentations

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages