# Engine API

Everything below is from `@liebstoeckel/engine` unless noted.

## Top-level

| Export | Kind | Purpose |
| --- | --- | --- |
| `Present` | component | the entry; routes to Deck / PresenterView / CaptureView |
| `Deck` · `DeckProps` | component | the audience/standalone view |
| `PresenterView` | component | the `#presenter` window |
| `CaptureView` | component | build-time thumbnail render |
| `normalizeSlides` · `SlideInput` | fn / type | normalize slide modules |

## Authoring

| Export | Kind | Purpose |
| --- | --- | --- |
| `Step` | component | a progressive reveal |
| `StepsProvider` | component | per-slide step tracker (the engine mounts this) |
| `useRevealState(count)` | hook | claim `count-1` reveal slots, get the active state index (for `CodeMagic`-like components) |
| `CodeMagic` | component | animated code; `steps`, `title?`, `lang?` |
| `TokenizedStep` · `CodeToken` | types | shape of macro output |
| `Magic` | component | Magic Move via shared `layoutId` |
| `Atmosphere` | component | animated gradient background (`still?`) |
| `Present`/`Deck` `transition` prop | prop | deck-wide slide transition; a slide can `export const transition` to override |
| `Present`/`Deck` `mobileTransitions` prop | prop | re-enable slide transitions on mobile (coarse pointer); off by default |
| `Present`/`Deck` `brandThemes` prop | prop | `Theme[]` of deck-defined brands, injected as `[data-brand]` CSS; reference by `name` in `brands` (see [theming](https://docs.liebstoeckel.app/guides/theming/)) |
| `resolveTransition` · `TRANSITIONS` · `DEFAULT_TRANSITION` | fn/const | resolve a name/custom spec → Motion variants; the built-in presets; the default (`"fade"`) |
| `SlideTransition` · `SlideTransitionName` · `SlideTransitionSpec` · `SlideDirection` | types | transition config (preset name `fade`/`blur`/`slide`/`zoom`/`none`, or a custom `{ variants, transition }`) |
| `Slot` · `PersistentProvider` · `PersistentLayer` · `PersistentItem` | components/type | persistent stateful elements |

## Layout

| Export | Kind | Purpose |
| --- | --- | --- |
| `ScaledStage` | component | fit the 1280×720 canvas to its parent |
| `SlideFrame` | component | brand bg + atmosphere + padded content |
| `STAGE_W` · `STAGE_H` | const | `1280` · `720` |

## Live & plugins

| Export | Kind | Purpose |
| --- | --- | --- |
| `Plugin` | component | place a plugin (`id`, `props?`, `components?`) |
| `LiveProvider` · `useLive` · `LiveContextValue` | component/hook/type | the live context |
| `detectLive` · `LiveInfo` | fn/type | is a live server connected? |
| `connectLive` · `LiveConnection` | fn/type | connect to a session over WebSocket |
| `useLiveDeck` · `getDeckIndex` · `setDeckIndex` · `DeckController` | hooks/fns/type | the synced slide/step controller |
| `getParticipantId` | fn | stable (or ephemeral) per-browser id |
| `mergeUi` | fn | merge author surface overrides |

## Navigation & delivery

`useDeckNav` (keyboard) plus pure helpers: `stepForward`, `stepBack`, `clampIndex`, `accumulateDigits`, `fullscreenAction`, `toggleFullscreen`.

## Thumbnails (runtime)

`readThumbnails()` → `ThumbnailSet | null`: the embedded thumbnail manifest, used by the overview grid.

## Build subpaths

| Import | Exports |
| --- | --- |
| `@liebstoeckel/engine/build` | `bundleDeck` (browser-free build primitive), `buildPluginManifest`, `buildServerBundle` |
| `@liebstoeckel/engine/code` (macro) | `codeStory`, `code` (import `with { type: "macro" }`) |
| `@liebstoeckel/engine/build/thumbnails` | `embedThumbnails`, `extractThumbnails`, `stripThumbnails` (the manifest format) |
| `@liebstoeckel/thumbnails` | `withThumbnails` (gated, never-fatal capture+embed), `captureThumbnails`, `addThumbnailsToFile`, `thumbnailsEnabled` |
| `@liebstoeckel/thumbnails/build` | `buildDeck`, **the default build**: `bundleDeck` + slide thumbnails |