import type { ReactNode } from 'react' import { Footer } from './chrome/Footer' import { Header } from './chrome/Header' import { Toc } from './chrome/Toc' import { Stage } from './Stage' import { stepMarker } from './stepMarker' import { usePresentationNav } from './usePresentationNav' import type { Mode, Step } from './types' export interface PresentationProps
= Record []
initialMode?: Mode
title?: string
/** Optional header brand. Omitted by default; pass a logo or title node to add one. */
brand?: ReactNode
/** Home link target for the header brand and the last-step footer button. */
homeHref?: string
/** Accessible label for the home link. */
homeLabel?: string
/** Full-bleed layer rendered behind the content. */
background?: ReactNode
/**
* Full-bleed layer rendered *above* the content (e.g. a CRT/scanline overlay).
* Unlike `background`, it paints over the chrome. Pointer events pass through,
* so it never intercepts clicks. Use `background` for true backdrops.
*/
overlay?: ReactNode
/**
* Override the per-step marker (top-right). Defaults to a zero-padded count.
* A callback (not a per-step field) so hosts can number relationally — e.g.
* skip chrome cards and count only body steps.
*/
marker?: (index: number, steps: Step []) => string
/** Small bottom-right attribution link. Defaults to and-scene; pass `null` for an intentional opt-out. */
attribution?: ReactNode
/** Attribution target; defaults to the and-scene GitHub repository. */
attributionHref?: string
}
export function Presentation = Record ) {
const { step, setStep, next, prev, last, mode } = usePresentationNav(steps.length, initialMode)
// An empty deck has no current step; render a clear placeholder instead of
// crashing on `steps[step].title`. (Hooks above run unconditionally first.)
if (steps.length === 0) {
return (