Skip to content

Page Templates

Page templates are full-slide layout primitives. Use them to decide the structure of a page before filling in block content.

AI Agent Guidance

When building a deck, follow this decision order:

  1. Choose a page template - determines the layout structure
  2. Choose block styles - fill the content areas with reusable blocks
  3. Configure props - customize title, variant, content

Rules for AI agents: - Use the simplest page template that faithfully represents the intent - Check src/page-templates/registry.ts for the canonical list - Only add a new page template when existing ones cannot express the page cleanly - Page templates accept React.ReactNode children - you can nest blocks inside them


Current Page Templates

1. hero - Hero Slide

Purpose: Title-first cover slide for deck opening and section transitions.

Source: src/shared/design-system/slide-templates/HeroSlideTemplate.tsx

Interface:

interface HeroSlideConfig {
  title: string;
  subtitle: string;
  metadata?: Array<{ label: string; value: string }>;
  variant?: 'default' | 'gradient' | 'dark';
  titleColor?: string;
}

Props:

Prop Type Required Default Description
title string - Main heading text
subtitle string - Secondary text below title
metadata Array<{label, value}> [] Key-value pairs displayed below subtitle
variant 'default' \| 'gradient' \| 'dark' 'default' Visual style variant
titleColor string theme default Custom title color (CSS color value)

Variants: - default - Standard dark text on light background - gradient - Gradient text effect using theme gradient - dark - Light text on dark background

Example:

import { HeroSlideTemplate } from '../shared/design-system/slide-templates';

<HeroSlideTemplate
  title="E3Pro Training"
  subtitle="Product overview and technical specifications"
  metadata={[
    { label: 'Version', value: 'v2.1' },
    { label: 'Duration', value: '45 min' }
  ]}
  variant="gradient"
/>

When to use: - Deck opening slide - Section divider/transition slides - Title-first communication


2. bullet-list - Bullet List Slide

Purpose: Single-column list slide for concise points.

Source: src/shared/design-system/slide-templates/BulletListSlideTemplate.tsx

Interface:

interface BulletListConfig {
  title: string;
  description?: string;
  items: Array<string | { text: string; highlight?: boolean }>;
  variant?: 'default' | 'dark';
}

Props:

Prop Type Required Default Description
title string - Slide title
description string undefined Optional description below title
items Array<string \| {text, highlight}> - List items (string or object with optional highlight)
variant 'default' \| 'dark' 'default' Visual style variant

Item format: - Simple string: "Point text" → rendered as bullet point - Object: { text: "Point text", highlight: true }bold bullet point

Example:

import { BulletListSlideTemplate } from '../shared/design-system/slide-templates';

<BulletListSlideTemplate
  title="Key Features"
  description="What makes E3Pro competitive"
  items={[
    'IP67 waterproof rating',
    'Integrated GPS + GLONASS',
    { text: '2-year warranty included', highlight: true },
    'Compatible with all OVES chargers'
  ]}
  variant="default"
/>

When to use: - Feature lists - Benefits enumeration - Key takeaways - Any sequential or unordered points


3. two-column - Two Column Slide

Purpose: Balanced comparison layout with left and right content areas.

Source: src/shared/design-system/slide-templates/TwoColumnSlideTemplate.tsx

Interface:

interface TwoColumnConfig {
  title: string;
  leftContent: React.ReactNode;
  rightContent: React.ReactNode;
  variant?: 'default' | 'dark';
}

Props:

Prop Type Required Default Description
title string - Slide title
leftContent React.ReactNode - Left column content (can be block component)
rightContent React.ReactNode - Right column content (can be block component)
variant 'default' \| 'dark' 'default' Visual style variant

Layout: CSS Grid, 2 equal columns (1fr 1fr), gap from theme spacing.

Example:

import { TwoColumnSlideTemplate } from '../shared/design-system/slide-templates';
import { StatCardsBlock } from '../blocks/StatCardsBlock';

<TwoColumnSlideTemplate
  title="Before vs After"
  leftContent={
    <StatCardsBlock
      cards={[
        { label: 'Range', value: '45km' },
        { label: 'Charge Time', value: '6h' }
      ]}
    />
  }
  rightContent={
    <StatCardsBlock
      cards={[
        { label: 'Range', value: '70km' },
        { label: 'Charge Time', value: '3.5h' }
      ]}
    />
  }
  variant="default"
/>

When to use: - Comparisons (before/after, old/new, competitor analysis) - Side-by-side feature breakdowns - Pros/cons layouts - Any content needing parallel structure


4. timeline - Timeline Slide

Purpose: Sequential roadmap layout for milestones and phases.

Source: src/shared/design-system/slide-templates/TimelineSlideTemplate.tsx

Interface:

interface TimelinePhase {
  title: string;
  description: string;
}

interface TimelineConfig {
  title: string;
  phases: TimelinePhase[];
  variant?: 'default' | 'dark';
}

Props:

Prop Type Required Default Description
title string - Slide title
phases Array<{title, description}> - Sequential phases/milestones
variant 'default' \| 'dark' 'default' Visual style variant

Phase object: - title (string, required) - Phase name (e.g., "Phase 1: Planning") - description (string, required) - Phase details

Example:

import { TimelineSlideTemplate } from '../shared/design-system/slide-templates';

<TimelineSlideTemplate
  title="Implementation Roadmap"
  phases={[
    {
      title: 'Phase 1: Setup',
      description: 'Install hardware and configure network'
    },
    {
      title: 'Phase 2: Pilot',
      description: 'Deploy to 5 locations, collect feedback'
    },
    {
      title: 'Phase 3: Rollout',
      description: 'Full deployment across all 50 locations'
    }
  ]}
  variant="default"
/>

When to use: - Project roadmaps - Implementation plans - Historical timelines - Process flows (sequential phases) - Milestone tracking


Page Template Selection Decision Tree

Start: What is the primary communication goal?

├─ Title/section opener?
│  └─ Use: hero
│
├─ List of points?
│  ├─ Sequential steps? → Use: bullet-list (consider numbered-list block)
│  └─ Unordered points? → Use: bullet-list
│
├─ Comparison?
│  ├─ Two sides? → Use: two-column
│  └─ Multi-item comparison? → Use: bullet-list + comparison-table block
│
├─ Timeline/roadmap?
│  └─ Use: timeline
│
└─ None of above?
   └─ Consider: two-column (most flexible for custom content)

Combining Page Templates with Blocks

Page templates define layout; blocks define content.

Pattern: Page template wraps blocks

// Example: bullet-list page with callout block
<BulletListSlideTemplate
  title="Action Items"
  items={[
    'Complete hardware installation',
    'Update firmware to v2.1',
    { text: 'Schedule training session', highlight: true }
  ]}
/>

// Example: two-column page with stat-cards block
<TwoColumnSlideTemplate
  title="Performance Metrics"
  leftContent={<StatCardsBlock cards={[...]} />}
  rightContent={<VennChartBlock sets={[...]} />}
/>

Key principle: Page templates accept React.ReactNode - you can pass: - Block components (recommended) - Raw JSX/HTML - Mixed content


Registry

Location: src/page-templates/registry.ts

The registry exports: - PageTemplateId - Union type of all valid page template IDs - PageTemplateDefinition - Interface for registry entries - pageTemplateRegistry - Record mapping IDs to definitions

Programmatic access:

import { pageTemplateRegistry } from '../page-templates/registry';

// Get all page template IDs
const availableTemplates = Object.keys(pageTemplateRegistry);
// → ['hero', 'bullet-list', 'two-column', 'timeline']

// Get example props for a template
const heroExample = pageTemplateRegistry['hero'].exampleProps;


Adding a New Page Template

Prerequisites: 1. The layout pattern must be reusable across multiple decks 2. Existing page templates cannot express the layout cleanly 3. You have a clear React.FC<ConfigInterface> component

Steps:

  1. Create component in src/shared/design-system/slide-templates/:

    // MyNewSlideTemplate.tsx
    export interface MyNewConfig {
      title: string;
      // ... other props
    }
    
    export const MyNewSlideTemplate: React.FC<MyNewConfig> = ({ title, ... }) => {
      return (
        <StyledSlide variant="default">
          <PageContentFrame title={title}>
            {/* Your layout */}
          </PageContentFrame>
        </StyledSlide>
      );
    };
    

  2. Register in src/page-templates/registry.ts:

    import { MyNewSlideTemplate } from '../shared/design-system/slide-templates/MyNewSlideTemplate';
    
    export type PageTemplateId = 'hero' | 'bullet-list' | 'two-column' | 'timeline' | 'my-new';
    
    export const pageTemplateRegistry: Record<PageTemplateId, PageTemplateDefinition> = {
      // ... existing entries
      'my-new': {
        id: 'my-new',
        title: 'My New Slide',
        description: 'Description for AI agents and humans.',
        component: MyNewSlideTemplate,
        exampleProps: {
          title: 'Example Title',
          // ... other example props
        }
      }
    };
    

  3. Export from src/page-templates/index.ts:

    export { pageTemplateRegistry, type PageTemplateId } from './registry';
    

  4. Document in docs/page-templates.md (this file) with:

  5. Purpose
  6. Interface
  7. Props table
  8. Example
  9. When to use
  10. AI agent guidance

  11. Test with npm run build:update:deck -- <your-test-deck>


Common Patterns

Pattern 1: Hero → Content → Timeline

Deck structure:
P1: hero (title slide)
P2: bullet-list (key points)
P3: two-column (comparison)
P4: timeline (implementation plan)

Pattern 2: Nesting Blocks in Two-Column

<TwoColumnSlideTemplate
  title="Technical Specs"
  leftContent={
    <div>
      <h3>Hardware</h3>
      <KeyValueTableBlock rows={[...]} />
    </div>
  }
  rightContent={
    <div>
      <h3>Software</h3>
      <BulletListBlock items={[...]} />
    </div>
  }
/>

Pattern 3: Highlighting Key Points

<BulletListSlideTemplate
  title="Critical Actions"
  items={[
    'Review safety protocols',
    { text: 'Complete certification by Friday', highlight: true },
    'Submit report to manager'
  ]}
/>

AI Agent MCP Integration

When an AI agent (e.g., WorkBuddy) receives a request to create or modify a deck, it should:

  1. Read this documentation to understand available page templates
  2. Check src/page-templates/registry.ts for the canonical, up-to-date list
  3. Match intent to page template using the decision tree above
  4. Validate props against the TypeScript interfaces
  5. Use example props from registry as starting point

MCP tool usage: - Use read_file to fetch src/page-templates/registry.ts - Use read_file to fetch individual slide template implementations - Use edit_file to update deck intent .md files - Use execute_command to run npm run build:update:deck after changes

Error prevention: - Always check that the page template ID exists in pageTemplateRegistry - Always provide required props (title is required for all templates) - Always match prop types (TypeScript interfaces are authoritative)


Source Files

File Purpose
src/page-templates/registry.ts Canonical registry (type definitions, registry object)
src/page-templates/index.ts Public exports
src/page-templates/README.md Developer notes
src/shared/design-system/slide-templates/*.tsx Implementations
src/shared/design-system/components.tsx StyledSlide, PageContentFrame
docs/page-templates.md This documentation

  • Block Styles: docs/block-library.md (content units that go inside page templates)
  • Deck Templates: docs/deck-templates.md (purpose-specific deck configurations)
  • System-Wide Layout: docs/system-wide-layout.md (header, footer, content area rules)
  • Deck Intents: docs/deck-intents.md (how to define deck structure with page templates)