BareGit
# Technical Design Document: Random Slides

## 1. Overview
"Random Slides" is a lightweight, browser-based slideshow application that allows users to create, edit, and play text-based slides using Markdown. The application operates entirely in the browser (Single Page Application) with no backend and requires no build steps. Data is persisted using the browser's `localStorage`.

## 2. Technical Constraints & Requirements
- **No Build Step**: Must use native ES Modules (ESM) and libraries available via CDN (UMD/ESM).
- **Pure Frontend**: No server-side logic.
- **Persistence**: `localStorage`.
- **Framework**: Preact (via `htm` for JSX-like syntax without transpilation).
- **Format**: Markdown for slide content.

## 3. Architecture

### 3.1 Tech Stack
- **Core Library**: `Preact` (imported via `esm.sh` or `unpkg`).
- **Templating**: `htm` (Hyperscript Tagged Markup) to write component layouts similar to JSX.
- **Markdown Renderer**: `marked` (via CDN).
- **Styling**: Standard CSS3.
- **State Management**: Preact standard `useState`, `useEffect`.

### 3.2 File Structure
Since there is no bundler, we will use standard ES modules.
```
/
├── index.html          # Entry point, loads styles and scripts
├── style.css           # Global styles
└── src/
    ├── main.js         # App entry and mount
    ├── App.js          # Main container and state manager
    ├── components/
    │   ├── Editor.js   # Edit mode view
    │   └── Player.js   # Play mode view
    └── utils/
        ├── storage.js  # LocalStorage wrapper
        ├── array.js    # Shuffle logic
        └── presets.js  # Pre-defined slideshow generators
```

## 4. Data Model

### 4.1 Slide Object
```javascript
{
  id: string,       // Unique UUID/ID for React keys and drag-drop tracking
  content: string   // Markdown text content
}
```

### 4.2 Application State
The `App` component will hold the central state:
- `slides`: `Array<SlideObject>` - The source of truth for all slides.
- `fontSize`: `number` - Base font size in pixels (default: 256).
- `mode`: `'edit' | 'play'` - Current application mode.
- `playDeck`: `Array<SlideObject>` - The subset/ordered list of slides currently being played (handling normal vs. shuffled).
- `currentIndex`: `number` - Current slide index in the `playDeck`.

## 5. Component Design

### 5.1 `App.js` (Container)
- **Responsibilities**:
    - Initialize state from `localStorage` (slides and settings).
    - Persist changes to `slides` and `settings` to `localStorage`.
    - Handle transitions between 'edit' and 'play' modes.
    - Handle "Play" vs "Shuffle Play" logic (generating the `playDeck`).
    - Manage `fontSize` state.

### 5.2 `Editor.js`
- **Props**: 
    - `slides`: Array of slides.
    - `fontSize`: Current font size setting.
    - `onUpdate`: Function to update the slides array.
    - `onUpdateFontSize`: Function to update the font size.
    - `onPlay`: Function to start normal playback.
    - `onShufflePlay`: Function to start shuffled playback.
- **Features**:
    - **Toolbar**: Organized into two rows.
        - Row 1: Title, Clear All button, Play buttons.
        - Row 2: Font Size input, Presets dropdown (A-Z, 1-20).
    - **Presets**: Load pre-defined slide decks (replacing current slides).
    - **Clear All**: Reset slideshow to a single empty slide.
    - **Slide List**: Renders a list of textareas.
    - **Drag and Drop**: Implemented using HTML5 Drag and Drop API.
    - **Actions**: Add Slide, Delete Slide.

### 5.3 `Player.js`
- **Props**:
    - `deck`: Array of slides to play.
    - `fontSize`: Base font size to apply.
    - `onExit`: Function to return to edit mode.
- **State**:
    - `index`: Internal tracking of current slide (initialized to 0).
- **Features**:
    - Renders current slide using `marked`.
    - **Style**: 
        - Apply `fontSize` (px).
        - Content centered horizontally (text-align) and vertically (flexbox).
    - **Event Listeners**:
        - `click` / `keydown` (any key except ESC): Advance slide.
        - `keydown` (ESC): Trigger `onExit`.
    - **Rendering**:
        - Centered, large text.
        - HTML rendered from Markdown (unsanitized as per requirements).

## 6. Key Workflows

### 6.1 Initialization
1. App loads.
2. `storage.js` reads key `random_slides_data`.
3. If null, return default `[{ id: uuid(), content: '' }]`.
4. App mounts in `mode: 'edit'`.

### 6.2 Editing
1. User types in textarea.
2. `onChange` triggers update to specific slide in `slides` array.
3. `useEffect` in `App` observes `slides` and saves to `localStorage`.

### 6.3 Drag and Drop Reordering
1. User drags a slide handle.
2. `dragstart`: Capture index.
3. `drop`: Calculate new index, splice array, update state.

### 6.4 Play Mode
1. User clicks "Play".
    - `playDeck` = `slides`.
    - `mode` = `'play'`.
2. User clicks "Shuffle".
    - `playDeck` = `shuffle(slides)`.
    - `mode` = `'play'`.

### 6.5 Navigation (Play Mode)
1. Render `playDeck[currentIndex]`.
2. Input event (Click/Key):
    - `currentIndex++`.
    - If `currentIndex >= playDeck.length`, show "End of Slideshow" or loop? (Default: Loop or Stop. Prd implies "advance", will implement loop or stop at last slide. Design decision: **Loop** for continuous flow, or **Stop** at end. Let's **Stop** at the end to avoid confusion).
3. ESC Key:
    - Call `onExit()`.
    - Reset `mode` to `'edit'`.

## 7. UI/UX Plan
- **Edit Mode**:
    - Clean vertical list of cards.
    - Each card has a handle (for dragging), textarea, and delete button.
    - Floating or sticky header/footer for "Add Slide", "Play", "Shuffle".
- **Play Mode**:
    - Full screen overlay or full viewport.
    - Minimalist.
    - Content vertically and horizontally centered.
    - High contrast text.

## 8. Third-Party Libraries (CDN)
- **Preact**: `https://esm.sh/preact`
- **Preact Hooks**: `https://esm.sh/preact/hooks`
- **htm**: `https://esm.sh/htm`
- **marked**: `https://esm.sh/marked`
- **uuid**: `https://esm.sh/uuid` (for reliable ID generation).