Lossless Changelog
product

Slides System — Auto-Discovery, Theme Integration, and Image Assets

RevealJS decks now find themselves from three different sources — component decks, standalone .astro pages, and plain markdown — and inherit the site theme properly, dark/light switching included.

Michael StatonMusic Editor

Changelog - 2025-12-14 (#1)

Hypernova Site: Slides System Implementation — Auto-Discovery, Theme Integration, and Image Assets

Overview

This sprint delivered a comprehensive RevealJS slides system for the Hypernova site with three major capabilities:

  1. Auto-Discovery — Presentations are automatically discovered from three sources: component decks, standalone .astro pages, and markdown files.

  2. Theme/Mode Integration — Slides properly inherit the Hypernova theme and respond to dark/light mode switching.

  3. Image Assets — Consistent coverImage/shareImage properties with intelligent fallbacks across all presentation types.

Key Achievement: A unified presentation system that supports both highly-designed component decks and quick markdown-based presentations, all with proper theming.


Architecture

src/pages/slides/
├── index.astro          ← Auto-discovers all presentations
├── [...slug].astro      ← Dynamic routing for all deck types
├── Global-CVC-for-Multinationals.astro  ← Standalone presentation
└── The-Future-of-CPG.astro              ← Standalone presentation

src/data/
├── componentDecks.ts    ← Registry for component-based decks
└── markdownDecks.ts     ← Loader for markdown content collection

src/layouts/
├── OneSlideDeck.astro       ← RevealJS wrapper with theme integration
└── MarkdownSlideDeck.astro  ← Markdown-to-slides converter

src/content/slides/
└── *.md                 ← Markdown presentations (slide separator: ---)

Presentation Discovery Flow

slides/index.astro
       │
       ├─► componentDecks.ts ──► Component Decks (hypernova-strategy)
       │
       ├─► import.meta.glob('./*.astro') ──► Standalone Pages
       │
       └─► markdownDecks.ts ──► Markdown Decks (institutional-grade, etc.)
       │
       ▼
Unified Presentation[] ──► TitleSlidePreviewCard ──► Grid Display

Changes by Area

1. Component Deck System

New: src/data/componentDecks.ts

Registry for component-based presentations with rich metadata:

TYPESCRIPT
export interface ComponentDeck {
  title: string;
  description: string;
  component: string;
  author?: string;
  date?: string;
  tags?: string[];
  type: 'component';

  // Image assets
  coverImage?: string;   // Card preview on index page
  shareImage?: string;   // OpenGraph/social sharing
}

export const componentDecks: Record<string, ComponentDeck> = {
  'hypernova-strategy': {
    title: 'Hypernova Fund-with-Funds Strategy',
    description: 'A differentiated approach to venture capital...',
    component: 'SlideShowHypernovaStrategy',
    author: 'Hypernova Capital',
    date: '2025-12-14',
    shareImage: '/share-banners/shareBanner__Hypernova-Cover.jpeg',
    type: 'component',
  }
};

Helper functions:

  • getComponentDeck(slug) — Get a single deck by slug

  • getAllComponentDecks() — Get all decks as array with slugs

2. Markdown Deck Auto-Loading

New: src/data/markdownDecks.ts

Dynamically loads markdown presentations from the slides content collection:

TYPESCRIPT
interface MarkdownDeckData {
  title: string;
  description: string;
  component: string;
  content?: string;
  coverImage?: string;
  shareImage?: string;
}

// Loads all markdown files from src/content/slides/*.md
const loadMarkdownDecks = async () => {
  const slides = await getCollection('slides');
  for (const slide of slides) {
    markdownDecks[slug] = {
      title: slide.data.title,
      description: slide.data.description,
      coverImage: slide.data.coverImage,
      shareImage: slide.data.shareImage,
      content: slide.body
    };
  }
};

3. Auto-Discovery in Index Page

Modified: src/pages/slides/index.astro

Unified presentation interface combining all three sources:

TYPESCRIPT
interface Presentation {
  title: string;
  slug: string;
  description: string;
  date?: string;
  author?: string;
  tags?: string[];
  icon?: string;
  coverImage?: string;  // For card display
  shareImage?: string;  // For OpenGraph
  type: 'component' | 'standalone' | 'markdown';
}

Discovery sources:

  1. Component decks from componentDecks.ts registry

  2. Standalone .astro pages via import.meta.glob('./*.astro') with lazy loading

  3. Markdown decks from markdownDecks.ts

Key fix: Changed from eager: true to lazy loading to prevent OneSlideDeck's CSS from leaking into the index page.

4. Theme/Mode Integration

Modified: src/layouts/OneSlideDeck.astro

Fixed theming to use Hypernova theme with proper dark mode:

ASTRO
<!-- Before -->
<html lang="en" data-theme="water">
import '@styles/water-theme.css';

<!-- After -->
<html lang="en" class="theme-hypernova dark" data-theme="hypernova" data-mode="dark">
import '@styles/nova-theme.css';

CSS Variables for slides:

CSS
:root {
  --slide-bg-primary: rgb(var(--color-primary-950));
  --slide-text-primary: rgb(var(--color-primary-50));
  --slide-text-secondary: rgb(var(--color-primary-100));
  --slide-accent: rgb(var(--color-accent-500));
  --slide-accent-bright: rgb(var(--color-accent-300));
}

5. MarkdownSlideDeck Rewrite

Modified: src/layouts/MarkdownSlideDeck.astro

Complete rewrite to fix broken nested HTML structure:

Before: Created its own <!DOCTYPE html> and nested BaseThemeLayout inside, causing theme conflicts.

After: Simply wraps content in OneSlideDeck:

ASTRO
<OneSlideDeck title={title} description={description}>
  <Fragment set:html={slidesHtml} />
</OneSlideDeck>

<style is:global>
  .slide h1 { color: var(--slide-text-primary); }
  .slide h2 { color: var(--slide-text-primary); }
  .slide p { color: var(--slide-text-secondary); }
  .slide strong { color: var(--slide-accent-bright); }
</style>

6. Mode-Responsive Preview Cards

Modified: src/components/slides/TitleSlidePreviewCard.astro

Refactored CSS to respond to dark/light mode:

CSS
/* Light mode defaults */
.presentation-card {
  background: var(--color-card);
  border: 1px solid var(--color-border);
}

/* Dark mode overrides */
:global(html[data-mode="dark"]) .presentation-card,
:global(html.dark) .presentation-card {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.1);
}

7. Image Asset Fallback System

Image property cascade:

TYPESCRIPT
// Card display: coverImage → shareImage → site default
const displayImage = coverImage || shareImage || DEFAULT_COVER_IMAGE;

// Share button: shareImage → coverImage → site default
image={shareImage || coverImage || DEFAULT_SHARE_IMAGE}

Default images created:

public/images/slides/
├── default-cover.jpg    # 1600x900 card preview
└── default-share.jpg    # 1200x630 OpenGraph

Files Changed Summary

New

  • src/data/componentDecks.ts — Component deck registry with metadata

  • src/data/markdownDecks.ts — Markdown deck auto-loader

  • src/components/slides/astro-decks/hypernova-strategy/ — 6-slide strategy deck

  • src/pages/slides/Global-CVC-for-Multinationals.astro — Standalone presentation

  • src/pages/slides/The-Future-of-CPG.astro — Standalone presentation

  • public/images/slides/default-cover.jpg — Default card preview image

  • public/images/slides/default-share.jpg — Default OpenGraph image

Modified

  • src/pages/slides/index.astro — Auto-discovery for all three presentation types

  • src/pages/slides/[...slug].astro — Dynamic routing for component + markdown decks

  • src/layouts/OneSlideDeck.astro — Theme/mode attributes fixed

  • src/layouts/MarkdownSlideDeck.astro — Complete rewrite for proper theme inheritance

  • src/components/slides/TitleSlidePreviewCard.astro — Mode-responsive CSS + image fallbacks

  • src/layouts/BoilerPlateHTML.astro — Removed redundant favicon fallback

  • tsconfig.json — Added @data/* path alias

Removed

  • Water Foundation themed decks (meet-at, variant-1) — Not appropriate for Hypernova site

  • src/content/markdown-memos/ from git tracking


Commits Included

  1. 001cccf — wip(slides): progress on rendering slides across complete-astro, components-astro

  2. b19b7ee — enhance(slides): enhance slides feature through autodiscovery of markdown slideshows

  3. 69c4510 — wip(slides): implemented theme sensitive styles and mode switching abilities


Notes / Follow-Ups

  • Markdown slides use --- as slide separators (horizontal rules)

  • Markdown presentations display with M↓ icon to distinguish from component decks

  • Consider adding date/author fields to markdown frontmatter for better sorting

  • The specification document at context-v/Slides-System-for-Astro-and-Markdown.md was updated with image asset naming conventions