promptslide 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/animation-config.ts","../src/core/animation-context.tsx","../src/core/animated.tsx","../src/core/transitions.ts","../src/core/morph.tsx","../src/core/use-slide-navigation.ts","../src/core/theme-context.tsx","../src/core/layouts/shared-footer.tsx","../src/core/slide-deck.tsx","../src/core/slide-error-boundary.tsx","../src/core/utils.ts"],"sourcesContent":["/**\n * Centralized animation configuration for the slide deck framework.\n * All animation timings, easings, and spring configs are defined here.\n */\n\n// =============================================================================\n// TIMING CONSTANTS\n// =============================================================================\n\n/** Duration for slide-to-slide transitions (seconds) */\nexport const SLIDE_TRANSITION_DURATION = 0.3\n\n/** Duration for morph/layout animations between slides (seconds) */\nexport const MORPH_DURATION = 0.8\n\n/** Duration for within-slide step animations (seconds) */\nexport const STEP_ANIMATION_DURATION = 0.4\n\n/** Default stagger delay for grouped animations (seconds) */\nexport const STAGGER_DELAY = 0.1\n\n// =============================================================================\n// EASING PRESETS\n// =============================================================================\n\nexport const EASE_DEFAULT = \"easeInOut\" as const\nexport const EASE_OUT = \"easeOut\" as const\nexport const EASE_IN = \"easeIn\" as const\n\n/** Smooth ease-in-out curve for morph animations (cubic bezier) */\nexport const EASE_MORPH = [0.4, 0, 0.2, 1] as const\n\n// =============================================================================\n// SPRING CONFIGURATIONS\n// =============================================================================\n\n/** Spring config for snappy, responsive animations */\nexport const SPRING_SNAPPY = {\n type: \"spring\" as const,\n stiffness: 300,\n damping: 30\n}\n\n/** Spring config for smooth, gentle animations */\nexport const SPRING_SMOOTH = {\n type: \"spring\" as const,\n stiffness: 200,\n damping: 25\n}\n\n/** Spring config for bouncy animations */\nexport const SPRING_BOUNCY = {\n type: \"spring\" as const,\n stiffness: 400,\n damping: 20\n}\n\n// =============================================================================\n// TRANSITION PRESETS\n// =============================================================================\n\n/** Standard transition for slide transitions */\nexport const SLIDE_TRANSITION = {\n duration: SLIDE_TRANSITION_DURATION,\n ease: EASE_DEFAULT\n} as const\n\n/** Standard transition for morph animations (smooth ease-in-out) */\nexport const MORPH_TRANSITION = {\n duration: MORPH_DURATION,\n ease: EASE_MORPH\n}\n\n/** Standard transition for step animations (spring-based, duration computed from stiffness/damping) */\nexport const STEP_TRANSITION = {\n ...SPRING_SNAPPY\n}\n\n// =============================================================================\n// DISTANCE CONSTANTS (pixels)\n// =============================================================================\n\n/** Distance for slide animations */\nexport const SLIDE_DISTANCE = 100\n\n/** Distance for within-slide element animations */\nexport const ELEMENT_SLIDE_DISTANCE = 30\n\n// =============================================================================\n// SLIDE DIMENSIONS\n// =============================================================================\n\n/** Standard slide dimensions (16:9 aspect ratio) */\nexport const SLIDE_DIMENSIONS = {\n width: 1280,\n height: 720,\n aspectRatio: 16 / 9\n} as const\n","import { createContext, useContext, useMemo } from \"react\"\n\ninterface AnimationContextValue {\n /** Current animation step (0 = no animations shown yet) */\n currentStep: number\n /** Total animation steps in this slide (declared in slide config) */\n totalSteps: number\n /** When true, all animation steps should be visible (used for backward navigation) */\n showAllAnimations: boolean\n}\n\nconst AnimationContext = createContext<AnimationContextValue>({\n currentStep: 0,\n totalSteps: 0,\n showAllAnimations: false\n})\n\ninterface AnimationProviderProps {\n children: React.ReactNode\n /** Current animation step (0 = no animations shown yet) */\n currentStep: number\n /** Total animation steps declared in slide config */\n totalSteps: number\n /** When true, show all animations regardless of currentStep (for backward navigation) */\n showAllAnimations?: boolean\n}\n\n/**\n * Provides animation context to child components.\n *\n * The totalSteps is now passed from parent (declared in slide config)\n * rather than discovered at runtime, eliminating race conditions.\n */\nexport function AnimationProvider({\n children,\n currentStep,\n totalSteps,\n showAllAnimations = false\n}: AnimationProviderProps) {\n const value = useMemo(\n () => ({\n currentStep,\n totalSteps,\n showAllAnimations\n }),\n [currentStep, totalSteps, showAllAnimations]\n )\n\n return <AnimationContext.Provider value={value}>{children}</AnimationContext.Provider>\n}\n\nexport function useAnimationContext() {\n return useContext(AnimationContext)\n}\n","import { motion, Variants } from \"framer-motion\"\n\nimport {\n ELEMENT_SLIDE_DISTANCE,\n SPRING_SNAPPY,\n STAGGER_DELAY,\n STEP_ANIMATION_DURATION\n} from \"./animation-config\"\nimport { useAnimationContext } from \"./animation-context\"\n\n// =============================================================================\n// ANIMATION TYPES & VARIANTS\n// =============================================================================\n\nexport type AnimationType =\n | \"fade\"\n | \"slide-up\"\n | \"slide-down\"\n | \"slide-left\"\n | \"slide-right\"\n | \"scale\"\n\nconst animationVariants: Record<AnimationType, Variants> = {\n fade: {\n hidden: { opacity: 0 },\n visible: { opacity: 1 }\n },\n \"slide-up\": {\n hidden: { opacity: 0, y: ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, y: 0 }\n },\n \"slide-down\": {\n hidden: { opacity: 0, y: -ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, y: 0 }\n },\n \"slide-left\": {\n hidden: { opacity: 0, x: ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, x: 0 }\n },\n \"slide-right\": {\n hidden: { opacity: 0, x: -ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, x: 0 }\n },\n scale: {\n hidden: { opacity: 0, scale: 0.8 },\n visible: { opacity: 1, scale: 1 }\n }\n}\n\ninterface AnimatedProps {\n /** Which step reveals this content (1-indexed) */\n step: number\n /** Animation type */\n animation?: AnimationType\n /** Animation duration in seconds */\n duration?: number\n /** Delay after trigger in seconds */\n delay?: number\n /** Custom className */\n className?: string\n children: React.ReactNode\n}\n\n/**\n * Animated element that appears at a specific animation step.\n *\n * The step count is now declared in slide config rather than discovered\n * at runtime, so this component simply consumes the context without\n * needing to register itself.\n */\nexport function Animated({\n step,\n animation = \"slide-up\",\n duration = STEP_ANIMATION_DURATION,\n delay = 0,\n className,\n children\n}: AnimatedProps) {\n const { currentStep, showAllAnimations } = useAnimationContext()\n\n // Show all animations when navigating backward, otherwise check step\n const isVisible = showAllAnimations || currentStep >= step\n\n return (\n <motion.div\n initial=\"hidden\"\n animate={isVisible ? \"visible\" : \"hidden\"}\n variants={animationVariants[animation]}\n transition={{\n ...SPRING_SNAPPY,\n duration,\n delay: isVisible ? delay : 0\n }}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n/**\n * Wrapper for staggering multiple children.\n * Each direct child will be animated in sequence.\n */\ninterface AnimatedGroupProps {\n /** Starting step for the first child */\n startStep: number\n /** Animation type for all children */\n animation?: AnimationType\n /** Delay between each child in seconds */\n staggerDelay?: number\n className?: string\n children: React.ReactNode\n}\n\nexport function AnimatedGroup({\n startStep,\n animation = \"slide-up\",\n staggerDelay = STAGGER_DELAY,\n className,\n children\n}: AnimatedGroupProps) {\n const { currentStep, showAllAnimations } = useAnimationContext()\n\n const childArray = Array.isArray(children) ? children : [children]\n\n // Show all animations when navigating backward, otherwise check step\n const isVisible = showAllAnimations || currentStep >= startStep\n\n const containerVariants: Variants = {\n hidden: {},\n visible: {\n transition: {\n staggerChildren: staggerDelay\n }\n }\n }\n\n return (\n <motion.div\n initial=\"hidden\"\n animate={isVisible ? \"visible\" : \"hidden\"}\n variants={containerVariants}\n className={className}\n >\n {childArray.map((child, index) => (\n <motion.div key={index} variants={animationVariants[animation]}>\n {child}\n </motion.div>\n ))}\n </motion.div>\n )\n}\n","/**\n * Slide transition variants for the slide deck framework.\n * These define how slides enter and exit during navigation.\n */\n\nimport type { Variants } from \"framer-motion\"\n\nimport {\n EASE_MORPH,\n MORPH_DURATION,\n SLIDE_DISTANCE,\n SLIDE_TRANSITION,\n SLIDE_TRANSITION_DURATION\n} from \"./animation-config\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type SlideTransitionType =\n | \"fade\"\n | \"slide-left\"\n | \"slide-right\"\n | \"slide-up\"\n | \"slide-down\"\n | \"zoom\"\n | \"zoom-fade\"\n | \"morph\"\n | \"none\"\n\nexport interface SlideTransitionConfig {\n /** The transition type */\n type: SlideTransitionType\n /** Optional custom duration (overrides default) */\n duration?: number\n /** Whether to use directional transitions based on navigation direction */\n directional?: boolean\n}\n\n// =============================================================================\n// STATIC VARIANTS (non-directional)\n// =============================================================================\n\nconst fadeVariants: Variants = {\n enter: { opacity: 0 },\n center: { opacity: 1 },\n exit: { opacity: 0 }\n}\n\nconst slideLeftVariants: Variants = {\n enter: { x: SLIDE_DISTANCE, opacity: 0 },\n center: { x: 0, opacity: 1 },\n exit: { x: -SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst slideRightVariants: Variants = {\n enter: { x: -SLIDE_DISTANCE, opacity: 0 },\n center: { x: 0, opacity: 1 },\n exit: { x: SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst slideUpVariants: Variants = {\n enter: { y: SLIDE_DISTANCE, opacity: 0 },\n center: { y: 0, opacity: 1 },\n exit: { y: -SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst slideDownVariants: Variants = {\n enter: { y: -SLIDE_DISTANCE, opacity: 0 },\n center: { y: 0, opacity: 1 },\n exit: { y: SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst zoomVariants: Variants = {\n enter: { scale: 0.8, opacity: 0 },\n center: { scale: 1, opacity: 1 },\n exit: { scale: 1.2, opacity: 0 }\n}\n\nconst zoomFadeVariants: Variants = {\n enter: { scale: 0.95, opacity: 0 },\n center: { scale: 1, opacity: 1 },\n exit: { scale: 1.05, opacity: 0 }\n}\n\nconst morphVariants: Variants = {\n enter: {\n opacity: 0,\n zIndex: 1\n },\n center: {\n opacity: 1,\n zIndex: 1,\n transition: {\n opacity: { delay: 0.05, duration: 0.25 }\n }\n },\n exit: {\n opacity: 0,\n zIndex: 0,\n transition: {\n opacity: { duration: MORPH_DURATION, ease: EASE_MORPH }\n }\n }\n}\n\nconst noneVariants: Variants = {\n enter: {},\n center: {},\n exit: {}\n}\n\n// =============================================================================\n// VARIANT REGISTRY\n// =============================================================================\n\nexport const SLIDE_VARIANTS: Record<SlideTransitionType, Variants> = {\n fade: fadeVariants,\n \"slide-left\": slideLeftVariants,\n \"slide-right\": slideRightVariants,\n \"slide-up\": slideUpVariants,\n \"slide-down\": slideDownVariants,\n zoom: zoomVariants,\n \"zoom-fade\": zoomFadeVariants,\n morph: morphVariants,\n none: noneVariants\n}\n\n// =============================================================================\n// DIRECTIONAL VARIANTS (based on navigation direction)\n// =============================================================================\n\nexport function createDirectionalVariants(axis: \"x\" | \"y\" = \"x\"): (direction: number) => Variants {\n return (direction: number) => ({\n enter: {\n [axis]: direction > 0 ? SLIDE_DISTANCE : -SLIDE_DISTANCE,\n opacity: 0\n },\n center: {\n [axis]: 0,\n opacity: 1\n },\n exit: {\n [axis]: direction < 0 ? SLIDE_DISTANCE : -SLIDE_DISTANCE,\n opacity: 0\n }\n })\n}\n\n/** Horizontal directional slide (left/right based on direction) */\nexport const directionalSlideX = createDirectionalVariants(\"x\")\n\n/** Vertical directional slide (up/down based on direction) */\nexport const directionalSlideY = createDirectionalVariants(\"y\")\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\nexport function getSlideVariants(\n config: SlideTransitionConfig | SlideTransitionType,\n direction: number = 1\n): Variants {\n const type = typeof config === \"string\" ? config : config.type\n const directional = typeof config === \"object\" ? config.directional : false\n\n if (directional && (type === \"slide-left\" || type === \"slide-right\")) {\n return directionalSlideX(direction)\n }\n\n if (directional && (type === \"slide-up\" || type === \"slide-down\")) {\n return directionalSlideY(direction)\n }\n\n return SLIDE_VARIANTS[type]\n}\n\nexport function getSlideTransition(config?: SlideTransitionConfig | SlideTransitionType): {\n duration: number\n ease: typeof SLIDE_TRANSITION.ease\n} {\n if (!config) return SLIDE_TRANSITION\n\n const type = typeof config === \"string\" ? config : config.type\n\n const defaultDuration = type === \"morph\" ? MORPH_DURATION : SLIDE_TRANSITION_DURATION\n\n const duration = typeof config === \"object\" && config.duration ? config.duration : defaultDuration\n\n return {\n ...SLIDE_TRANSITION,\n duration\n }\n}\n\n// =============================================================================\n// DEFAULT EXPORT\n// =============================================================================\n\nexport const DEFAULT_SLIDE_TRANSITION: SlideTransitionType = \"fade\"\n","import type { Transition } from \"framer-motion\"\n\nimport { motion } from \"framer-motion\"\n\nimport { MORPH_TRANSITION } from \"./animation-config\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface MorphProps {\n layoutId: string\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\ninterface MorphGroupProps {\n groupId: string\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\n// =============================================================================\n// MORPH COMPONENT\n// =============================================================================\n\n/**\n * Wrapper component that enables morph/shared-layout animations between slides.\n *\n * Usage:\n * ```tsx\n * // Slide 1 - Large version\n * <Morph layoutId=\"hero-title\">\n * <h1 className=\"text-6xl\">Title</h1>\n * </Morph>\n *\n * // Slide 2 - Small version (same layoutId = morphs between them)\n * <Morph layoutId=\"hero-title\">\n * <h1 className=\"text-2xl\">Title</h1>\n * </Morph>\n * ```\n */\nexport function Morph({\n layoutId,\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphProps) {\n return (\n <motion.div\n layout\n layoutId={layoutId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n// =============================================================================\n// MORPH GROUP COMPONENT\n// =============================================================================\n\nexport function MorphGroup({\n groupId,\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphGroupProps) {\n return (\n <motion.div\n layout\n layoutId={groupId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n// =============================================================================\n// MORPH ITEM (for use within MorphGroup pattern)\n// =============================================================================\n\ninterface MorphItemProps {\n id: string\n prefix?: string\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\nexport function MorphItem({\n id,\n prefix,\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphItemProps) {\n const layoutId = prefix ? `${prefix}-${id}` : id\n\n return (\n <motion.div\n layout\n layoutId={layoutId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n// =============================================================================\n// MORPH TEXT (specialized for text that changes size)\n// =============================================================================\n\ninterface MorphTextProps {\n layoutId: string\n as?: \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\"\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\nexport function MorphText({\n layoutId,\n as: Component = \"span\",\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphTextProps) {\n const MotionComponent = motion[Component]\n\n return (\n <MotionComponent\n layout\n layoutId={layoutId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </MotionComponent>\n )\n}\n","import { useCallback, useEffect, useState } from \"react\"\n\nimport type { NavigationDirection, SlideConfig } from \"./types\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ntype NavigationStatus = \"idle\" | \"transitioning\"\n\ntype QueuedAction = \"advance\" | \"goBack\" | null\n\ninterface NavigationState {\n status: NavigationStatus\n direction: NavigationDirection\n}\n\nexport interface UseSlideNavigationOptions {\n slides: SlideConfig[]\n initialSlide?: number\n onSlideChange?: (slideIndex: number) => void\n}\n\nexport interface UseSlideNavigationReturn {\n currentSlide: number\n animationStep: number\n totalSteps: number\n direction: NavigationDirection\n isTransitioning: boolean\n showAllAnimations: boolean\n advance: () => void\n goBack: () => void\n goToSlide: (index: number) => void\n onTransitionComplete: () => void\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\nexport function useSlideNavigation({\n slides,\n initialSlide = 0,\n onSlideChange\n}: UseSlideNavigationOptions): UseSlideNavigationReturn {\n const [currentSlide, setCurrentSlide] = useState(initialSlide)\n const [animationStep, setAnimationStep] = useState(0)\n\n const [navState, setNavState] = useState<NavigationState>({\n status: \"idle\",\n direction: 0\n })\n\n const [queuedAction, setQueuedAction] = useState<QueuedAction>(null)\n\n const totalSteps = slides[currentSlide]?.steps ?? 0\n\n const onTransitionComplete = useCallback(() => {\n setNavState(prev => {\n if (prev.status === \"transitioning\") {\n return { status: \"idle\", direction: 0 }\n }\n return prev\n })\n }, [])\n\n const advance = useCallback(() => {\n if (navState.status === \"transitioning\") {\n setQueuedAction(\"advance\")\n return\n }\n\n const currentTotalSteps = slides[currentSlide]?.steps ?? 0\n\n if (animationStep >= currentTotalSteps) {\n const nextSlide = (currentSlide + 1) % slides.length\n setNavState({ status: \"transitioning\", direction: 1 })\n setAnimationStep(0)\n setCurrentSlide(nextSlide)\n onSlideChange?.(nextSlide)\n } else {\n setAnimationStep(prev => prev + 1)\n }\n }, [navState.status, animationStep, currentSlide, slides, onSlideChange])\n\n const goBack = useCallback(() => {\n if (navState.status === \"transitioning\") {\n setQueuedAction(\"goBack\")\n return\n }\n\n if (animationStep <= 0) {\n const prevSlide = (currentSlide - 1 + slides.length) % slides.length\n const prevSlideSteps = slides[prevSlide]?.steps ?? 0\n setNavState({ status: \"transitioning\", direction: -1 })\n setAnimationStep(prevSlideSteps)\n setCurrentSlide(prevSlide)\n onSlideChange?.(prevSlide)\n } else {\n setAnimationStep(prev => prev - 1)\n }\n }, [navState.status, animationStep, currentSlide, slides, onSlideChange])\n\n const goToSlide = useCallback(\n (index: number) => {\n if (index < 0 || index >= slides.length || index === currentSlide) {\n return\n }\n\n const direction = index > currentSlide ? 1 : -1\n setNavState({ status: \"transitioning\", direction })\n setAnimationStep(0)\n setCurrentSlide(index)\n onSlideChange?.(index)\n },\n [currentSlide, slides.length, onSlideChange]\n )\n\n useEffect(() => {\n if (navState.status === \"idle\" && queuedAction !== null) {\n setQueuedAction(null)\n if (queuedAction === \"advance\") {\n advance()\n } else if (queuedAction === \"goBack\") {\n goBack()\n }\n }\n }, [navState.status, queuedAction, advance, goBack])\n\n return {\n currentSlide,\n animationStep,\n totalSteps,\n direction: navState.direction,\n isTransitioning: navState.status !== \"idle\",\n showAllAnimations: navState.direction === -1 && navState.status === \"transitioning\",\n advance,\n goBack,\n goToSlide,\n onTransitionComplete\n }\n}\n","import { createContext, useContext, useMemo } from \"react\"\nimport type { ThemeConfig } from \"./types\"\n\nconst ThemeContext = createContext<ThemeConfig | null>(null)\n\n/**\n * Access the full theme config. Returns null outside SlideThemeProvider.\n */\nexport function useTheme(): ThemeConfig | null {\n return useContext(ThemeContext)\n}\n\nfunction buildCssOverrides(theme: ThemeConfig): React.CSSProperties {\n const style: Record<string, string> = {}\n\n if (theme.colors?.primary) style[\"--primary\"] = theme.colors.primary\n if (theme.colors?.primaryForeground) style[\"--primary-foreground\"] = theme.colors.primaryForeground\n if (theme.colors?.secondary) style[\"--secondary\"] = theme.colors.secondary\n if (theme.colors?.secondaryForeground) style[\"--secondary-foreground\"] = theme.colors.secondaryForeground\n if (theme.colors?.accent) style[\"--accent\"] = theme.colors.accent\n if (theme.colors?.accentForeground) style[\"--accent-foreground\"] = theme.colors.accentForeground\n\n if (theme.fonts?.heading) style[\"--font-heading\"] = theme.fonts.heading\n if (theme.fonts?.body) style[\"--font-body\"] = theme.fonts.body\n\n return style as React.CSSProperties\n}\n\ninterface SlideThemeProviderProps {\n theme: ThemeConfig\n children: React.ReactNode\n}\n\n/**\n * Provides the full theme to all descendants.\n * Injects CSS variable overrides via inline style.\n */\nexport function SlideThemeProvider({ theme, children }: SlideThemeProviderProps) {\n const cssOverrides = useMemo(() => buildCssOverrides(theme), [theme])\n\n return (\n <ThemeContext.Provider value={theme}>\n <div style={cssOverrides} className=\"contents\">\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n","import { useTheme } from \"../theme-context\"\n\ninterface SlideFooterProps {\n slideNumber: number\n totalSlides: number\n /** Use light text/logo for dark slide backgrounds */\n variant?: \"default\" | \"light\"\n}\n\nexport function SlideFooter({ slideNumber, totalSlides, variant = \"default\" }: SlideFooterProps) {\n const theme = useTheme()\n if (!theme) return null\n\n const logoUrl = variant === \"light\"\n ? (theme.logo?.fullLight ?? theme.logo?.full)\n : theme.logo?.full\n\n const textClass = variant === \"light\"\n ? \"text-white/70\"\n : \"text-muted-foreground\"\n\n const nameClass = variant === \"light\"\n ? \"text-white font-semibold\"\n : \"text-foreground font-semibold\"\n\n return (\n <div className={`mt-4 flex shrink-0 items-center justify-between text-sm ${textClass}`}>\n <div className={`flex items-center gap-3 tracking-tight ${nameClass}`}>\n {logoUrl && (\n <img\n src={logoUrl}\n alt={`${theme.name} Logo`}\n className=\"h-8 w-auto\"\n />\n )}\n <span className=\"text-lg\">{theme.name}</span>\n </div>\n <div className=\"font-mono\">\n {slideNumber} / {totalSlides}\n </div>\n </div>\n )\n}\n","import { AnimatePresence, LayoutGroup, motion } from \"framer-motion\"\nimport { ChevronLeft, ChevronRight, Download, Grid3X3, List, Maximize, Monitor } from \"lucide-react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nimport type { SlideTransitionType } from \"./transitions\"\nimport type { SlideConfig } from \"./types\"\n\nimport { SLIDE_DIMENSIONS, SLIDE_TRANSITION } from \"./animation-config\"\nimport { AnimationProvider } from \"./animation-context\"\nimport { SlideErrorBoundary } from \"./slide-error-boundary\"\nimport { DEFAULT_SLIDE_TRANSITION, getSlideVariants } from \"./transitions\"\nimport { useSlideNavigation } from \"./use-slide-navigation\"\nimport { cn } from \"./utils\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ntype ViewMode = \"slide\" | \"list\" | \"grid\"\n\ninterface SlideDeckProps {\n slides: SlideConfig[]\n transition?: SlideTransitionType\n directionalTransition?: boolean\n}\n\n// =============================================================================\n// EXPORT VIEW (for Playwright screenshot capture)\n// =============================================================================\n\nfunction SlideExportView({ slides, slideIndex }: { slides: SlideConfig[]; slideIndex: number }) {\n const [ready, setReady] = useState(false)\n const clampedIndex = Math.max(0, Math.min(slideIndex, slides.length - 1))\n const slideConfig = slides[clampedIndex]!\n const SlideComponent = slideConfig.component\n\n useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <div\n data-export-ready={ready ? \"true\" : undefined}\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n overflow: \"hidden\",\n position: \"relative\",\n background: \"black\"\n }}\n >\n <AnimationProvider\n currentStep={slideConfig.steps}\n totalSteps={slideConfig.steps}\n showAllAnimations={true}\n >\n <SlideErrorBoundary slideIndex={clampedIndex} slideTitle={slideConfig.title}>\n <SlideComponent slideNumber={clampedIndex + 1} totalSlides={slides.length} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n )\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function SlideDeck({ slides, transition, directionalTransition }: SlideDeckProps) {\n // Check for export mode via URL params\n const [exportParams] = useState(() => {\n if (typeof window === \"undefined\") return null\n const params = new URLSearchParams(window.location.search)\n if (params.get(\"export\") !== \"true\") return null\n return { slideIndex: parseInt(params.get(\"slide\") || \"0\", 10) }\n })\n\n if (exportParams) {\n return <SlideExportView slides={slides} slideIndex={exportParams.slideIndex} />\n }\n\n const [viewMode, setViewMode] = useState<ViewMode>(\"slide\")\n const [isPresentationMode, setIsPresentationMode] = useState(false)\n const [scale, setScale] = useState(1)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const {\n currentSlide,\n animationStep,\n totalSteps,\n direction,\n showAllAnimations,\n advance,\n goBack,\n goToSlide,\n onTransitionComplete\n } = useSlideNavigation({\n slides\n })\n\n const togglePresentationMode = useCallback(async () => {\n if (!document.fullscreenElement) {\n await document.documentElement.requestFullscreen()\n } else {\n await document.exitFullscreen()\n }\n }, [])\n\n // Listen for fullscreen changes\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsPresentationMode(!!document.fullscreenElement)\n }\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange)\n return () => document.removeEventListener(\"fullscreenchange\", handleFullscreenChange)\n }, [])\n\n // Calculate scale factor for presentation mode\n useEffect(() => {\n const calculateScale = () => {\n if (!isPresentationMode) {\n setScale(1)\n return\n }\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n const scaleX = viewportWidth / SLIDE_DIMENSIONS.width\n const scaleY = viewportHeight / SLIDE_DIMENSIONS.height\n setScale(Math.min(scaleX, scaleY))\n }\n\n calculateScale()\n window.addEventListener(\"resize\", calculateScale)\n return () => window.removeEventListener(\"resize\", calculateScale)\n }, [isPresentationMode])\n\n const handleExportPdf = () => {\n const previousMode = viewMode\n setViewMode(\"list\")\n\n setTimeout(() => {\n const handleAfterPrint = () => {\n setViewMode(previousMode)\n window.removeEventListener(\"afterprint\", handleAfterPrint)\n }\n window.addEventListener(\"afterprint\", handleAfterPrint)\n window.print()\n }, 100)\n }\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"f\" || e.key === \"F\") {\n togglePresentationMode()\n return\n }\n\n // G for grid view toggle\n if (e.key === \"g\" || e.key === \"G\") {\n setViewMode(prev => (prev === \"grid\" ? \"slide\" : \"grid\"))\n return\n }\n\n if (viewMode !== \"slide\") return\n\n if (e.key === \"ArrowRight\" || e.key === \" \") {\n e.preventDefault()\n advance()\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault()\n goBack()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [advance, goBack, viewMode, togglePresentationMode])\n\n // Per-slide transition resolution\n const currentSlideTransition = slides[currentSlide]?.transition\n const transitionType = currentSlideTransition ?? transition ?? DEFAULT_SLIDE_TRANSITION\n const isDirectional = directionalTransition ?? false\n\n const slideVariants = getSlideVariants(\n { type: transitionType, directional: isDirectional },\n direction\n )\n\n const CurrentSlideComponent = slides[currentSlide]!.component\n\n return (\n <div className=\"min-h-screen w-full bg-neutral-950 text-foreground\">\n <style>{`\n @media print {\n @page {\n size: 1920px 1080px;\n margin: 0;\n }\n html,\n body {\n width: 100%;\n height: 100%;\n margin: 0 !important;\n padding: 0 !important;\n overflow: visible !important;\n }\n body {\n print-color-adjust: exact;\n -webkit-print-color-adjust: exact;\n background: transparent !important;\n }\n }\n `}</style>\n\n {/* Toolbar */}\n <div\n className={cn(\n \"fixed top-4 right-4 z-50 flex gap-1 rounded-lg border border-neutral-800 bg-neutral-950/90 p-1 backdrop-blur-sm print:hidden\",\n isPresentationMode && \"hidden\"\n )}\n >\n <button\n onClick={() => setViewMode(\"slide\")}\n className={cn(\n \"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\",\n viewMode === \"slide\" && \"bg-neutral-800 text-white\"\n )}\n title=\"Presentation View\"\n >\n <Monitor className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode(\"list\")}\n className={cn(\n \"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\",\n viewMode === \"list\" && \"bg-neutral-800 text-white\"\n )}\n title=\"List View\"\n >\n <List className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode(\"grid\")}\n className={cn(\n \"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\",\n viewMode === \"grid\" && \"bg-neutral-800 text-white\"\n )}\n title=\"Grid View\"\n >\n <Grid3X3 className=\"h-4 w-4\" />\n </button>\n\n <div className=\"mx-1 w-px bg-neutral-800\" />\n\n <button\n onClick={handleExportPdf}\n className=\"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\"\n title=\"Download PDF\"\n >\n <Download className=\"h-4 w-4\" />\n </button>\n <button\n onClick={togglePresentationMode}\n className=\"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\"\n title=\"Present (F)\"\n >\n <Maximize className=\"h-4 w-4\" />\n </button>\n </div>\n\n {/* Slide View */}\n {viewMode === \"slide\" && (\n <div\n ref={containerRef}\n role=\"presentation\"\n tabIndex={isPresentationMode ? 0 : undefined}\n className={cn(\n \"flex h-screen w-full flex-col items-center justify-center overflow-hidden print:hidden\",\n isPresentationMode ? \"bg-black p-0\" : \"p-4 md:p-8\"\n )}\n onClick={isPresentationMode ? advance : undefined}\n onKeyDown={\n isPresentationMode\n ? e => {\n if (e.key === \"Enter\" || e.key === \" \") advance()\n }\n : undefined\n }\n >\n <LayoutGroup id=\"slide-deck\">\n {isPresentationMode ? (\n <div\n className=\"pointer-events-none relative overflow-hidden bg-black\"\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n transform: `scale(${scale})`,\n transformOrigin: \"center center\"\n }}\n >\n <AnimatePresence initial={false}>\n <motion.div\n key={currentSlide}\n variants={slideVariants}\n initial=\"enter\"\n animate=\"center\"\n exit=\"exit\"\n transition={SLIDE_TRANSITION}\n onAnimationComplete={definition => {\n if (definition === \"center\") {\n onTransitionComplete()\n }\n }}\n className=\"absolute inset-0 h-full w-full\"\n >\n <AnimationProvider\n currentStep={animationStep}\n totalSteps={totalSteps}\n showAllAnimations={showAllAnimations}\n >\n <SlideErrorBoundary\n slideIndex={currentSlide}\n slideTitle={slides[currentSlide]?.title}\n >\n <CurrentSlideComponent\n slideNumber={currentSlide + 1}\n totalSlides={slides.length}\n />\n </SlideErrorBoundary>\n </AnimationProvider>\n </motion.div>\n </AnimatePresence>\n </div>\n ) : (\n <div className=\"relative aspect-video w-full max-w-7xl overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-2xl\">\n <AnimatePresence initial={false}>\n <motion.div\n key={currentSlide}\n variants={slideVariants}\n initial=\"enter\"\n animate=\"center\"\n exit=\"exit\"\n transition={SLIDE_TRANSITION}\n onAnimationComplete={definition => {\n if (definition === \"center\") {\n onTransitionComplete()\n }\n }}\n className=\"absolute inset-0 h-full w-full\"\n >\n <AnimationProvider\n currentStep={animationStep}\n totalSteps={totalSteps}\n showAllAnimations={showAllAnimations}\n >\n <SlideErrorBoundary\n slideIndex={currentSlide}\n slideTitle={slides[currentSlide]?.title}\n >\n <CurrentSlideComponent\n slideNumber={currentSlide + 1}\n totalSlides={slides.length}\n />\n </SlideErrorBoundary>\n </AnimationProvider>\n </motion.div>\n </AnimatePresence>\n </div>\n )}\n </LayoutGroup>\n\n {/* Navigation Controls */}\n {!isPresentationMode && (\n <div className=\"mt-6 flex items-center gap-4\">\n <button\n onClick={goBack}\n className=\"rounded-full border border-neutral-800 bg-black/50 p-2 text-neutral-400 backdrop-blur-sm transition-colors hover:bg-neutral-900 hover:text-white\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </button>\n <div className=\"flex min-w-[4rem] flex-col items-center\">\n <span className=\"font-mono text-sm text-neutral-500\">\n {currentSlide + 1} / {slides.length}\n </span>\n {slides[currentSlide]?.title && (\n <span className=\"mt-0.5 text-xs text-neutral-600\">\n {slides[currentSlide].title}\n </span>\n )}\n </div>\n <button\n onClick={advance}\n className=\"rounded-full border border-neutral-800 bg-black/50 p-2 text-neutral-400 backdrop-blur-sm transition-colors hover:bg-neutral-900 hover:text-white\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </div>\n )}\n </div>\n )}\n\n {/* Grid View */}\n {viewMode === \"grid\" && (\n <div className=\"mx-auto max-w-7xl p-8 pt-16 print:hidden\">\n <div className=\"grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4\">\n {slides.map((slideConfig, index) => {\n const SlideComponent = slideConfig.component\n const prevSection = index > 0 ? slides[index - 1]?.section : undefined\n const showSectionHeader = slideConfig.section && slideConfig.section !== prevSection\n\n return (\n <div key={index} className={showSectionHeader ? \"col-span-full\" : undefined}>\n {showSectionHeader && (\n <h3 className=\"mt-4 mb-3 text-xs font-bold tracking-[0.2em] text-neutral-500 uppercase first:mt-0\">\n {slideConfig.section}\n </h3>\n )}\n <button\n onClick={() => {\n goToSlide(index)\n setViewMode(\"slide\")\n }}\n className=\"group relative aspect-video w-full overflow-hidden rounded-lg border border-neutral-800 bg-black shadow-sm transition-all hover:border-primary hover:shadow-lg hover:shadow-primary/10\"\n >\n <div\n className=\"h-full w-full origin-top-left scale-[0.25]\"\n style={{ width: \"400%\", height: \"400%\" }}\n >\n <SlideErrorBoundary slideIndex={index} slideTitle={slideConfig.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={slides.length} />\n </SlideErrorBoundary>\n </div>\n <div className=\"absolute inset-0 bg-black/0 transition-colors group-hover:bg-black/20\" />\n <div className=\"absolute bottom-2 left-2 rounded bg-black/70 px-2 py-1 text-xs font-medium text-white\">\n {slideConfig.title ? `${index + 1}. ${slideConfig.title}` : index + 1}\n </div>\n </button>\n </div>\n )\n })}\n </div>\n </div>\n )}\n\n {/* List View */}\n <div\n className={cn(\n \"mx-auto max-w-7xl p-8 pt-16\",\n \"print:m-0 print:block print:max-w-none print:p-0\",\n viewMode === \"list\" ? \"block\" : \"hidden print:block\"\n )}\n >\n <div className=\"grid grid-cols-1 gap-8 print:block\">\n {slides.map((slideConfig, index) => {\n const SlideComponent = slideConfig.component\n return (\n <div\n key={index}\n className=\"aspect-video w-full overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-sm print:relative print:m-0 print:h-[1080px] print:w-[1920px] print:break-after-page print:overflow-hidden print:rounded-none print:border-0 print:shadow-none\"\n >\n <div className=\"h-full w-full print:h-[720px] print:w-[1280px] print:origin-top-left print:scale-[1.5]\">\n <AnimationProvider\n currentStep={slideConfig.steps}\n totalSteps={slideConfig.steps}\n showAllAnimations={true}\n >\n <SlideErrorBoundary slideIndex={index} slideTitle={slideConfig.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={slides.length} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n </div>\n )\n}\n","import React from \"react\"\n\ninterface SlideErrorBoundaryProps {\n slideIndex: number\n slideTitle?: string\n children: React.ReactNode\n}\n\ninterface SlideErrorBoundaryState {\n hasError: boolean\n error: Error | null\n}\n\nexport class SlideErrorBoundary extends React.Component<\n SlideErrorBoundaryProps,\n SlideErrorBoundaryState\n> {\n state: SlideErrorBoundaryState = { hasError: false, error: null }\n\n static getDerivedStateFromError(error: Error) {\n return { hasError: true, error }\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n console.error(\n `[PromptSlide] Slide ${this.props.slideIndex + 1}${this.props.slideTitle ? ` (\"${this.props.slideTitle}\")` : \"\"} crashed:`,\n error,\n errorInfo\n )\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <div className=\"flex h-full w-full flex-col items-center justify-center bg-red-950/20 p-12\">\n <div className=\"mb-4 text-lg font-semibold text-red-400\">\n Slide {this.props.slideIndex + 1} Error\n {this.props.slideTitle && (\n <span className=\"ml-2 font-normal text-red-400/70\">({this.props.slideTitle})</span>\n )}\n </div>\n <div className=\"max-w-2xl text-center font-mono text-sm break-words text-red-300/80\">\n {this.state.error?.message ?? \"Unknown error\"}\n </div>\n </div>\n )\n }\n return this.props.children\n }\n}\n","import type { ClassValue } from \"clsx\"\n\nimport { clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":"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","names":["jsx","motion","jsx","motion","createContext","useContext","useMemo","jsx","jsx","motion","useCallback","useEffect","useState","jsx","jsxs","jsx","jsxs","useState","useEffect","useCallback","motion"]}
1
+ {"version":3,"sources":["../src/core/animation-config.ts","../src/core/animation-context.tsx","../src/core/animated.tsx","../src/core/transitions.ts","../src/core/morph.tsx","../src/core/use-slide-navigation.ts","../src/core/theme-context.tsx","../src/core/layouts/shared-footer.tsx","../src/core/slide-renderer.tsx","../src/core/slide-error-boundary.tsx","../src/core/slide-embed.tsx","../src/core/slide-deck.tsx","../src/core/utils.ts"],"sourcesContent":["/**\n * Centralized animation configuration for the slide deck framework.\n * All animation timings, easings, and spring configs are defined here.\n */\n\n// =============================================================================\n// TIMING CONSTANTS\n// =============================================================================\n\n/** Duration for slide-to-slide transitions (seconds) */\nexport const SLIDE_TRANSITION_DURATION = 0.3\n\n/** Duration for morph/layout animations between slides (seconds) */\nexport const MORPH_DURATION = 0.8\n\n/** Duration for within-slide step animations (seconds) */\nexport const STEP_ANIMATION_DURATION = 0.4\n\n/** Default stagger delay for grouped animations (seconds) */\nexport const STAGGER_DELAY = 0.1\n\n// =============================================================================\n// EASING PRESETS\n// =============================================================================\n\nexport const EASE_DEFAULT = \"easeInOut\" as const\nexport const EASE_OUT = \"easeOut\" as const\nexport const EASE_IN = \"easeIn\" as const\n\n/** Smooth ease-in-out curve for morph animations (cubic bezier) */\nexport const EASE_MORPH = [0.4, 0, 0.2, 1] as const\n\n// =============================================================================\n// SPRING CONFIGURATIONS\n// =============================================================================\n\n/** Spring config for snappy, responsive animations */\nexport const SPRING_SNAPPY = {\n type: \"spring\" as const,\n stiffness: 300,\n damping: 30\n}\n\n/** Spring config for smooth, gentle animations */\nexport const SPRING_SMOOTH = {\n type: \"spring\" as const,\n stiffness: 200,\n damping: 25\n}\n\n/** Spring config for bouncy animations */\nexport const SPRING_BOUNCY = {\n type: \"spring\" as const,\n stiffness: 400,\n damping: 20\n}\n\n// =============================================================================\n// TRANSITION PRESETS\n// =============================================================================\n\n/** Standard transition for slide transitions */\nexport const SLIDE_TRANSITION = {\n duration: SLIDE_TRANSITION_DURATION,\n ease: EASE_DEFAULT\n} as const\n\n/** Standard transition for morph animations (smooth ease-in-out) */\nexport const MORPH_TRANSITION = {\n duration: MORPH_DURATION,\n ease: EASE_MORPH\n}\n\n/** Standard transition for step animations (spring-based, duration computed from stiffness/damping) */\nexport const STEP_TRANSITION = {\n ...SPRING_SNAPPY\n}\n\n// =============================================================================\n// DISTANCE CONSTANTS (pixels)\n// =============================================================================\n\n/** Distance for slide animations */\nexport const SLIDE_DISTANCE = 100\n\n/** Distance for within-slide element animations */\nexport const ELEMENT_SLIDE_DISTANCE = 30\n\n// =============================================================================\n// SLIDE DIMENSIONS\n// =============================================================================\n\n/** Standard slide dimensions (16:9 aspect ratio) */\nexport const SLIDE_DIMENSIONS = {\n width: 1280,\n height: 720,\n aspectRatio: 16 / 9\n} as const\n","import { createContext, useContext, useMemo } from \"react\"\n\ninterface AnimationContextValue {\n /** Current animation step (0 = no animations shown yet) */\n currentStep: number\n /** Total animation steps in this slide (declared in slide config) */\n totalSteps: number\n /** When true, all animation steps should be visible (used for backward navigation) */\n showAllAnimations: boolean\n}\n\nconst AnimationContext = createContext<AnimationContextValue>({\n currentStep: 0,\n totalSteps: 0,\n showAllAnimations: false\n})\n\ninterface AnimationProviderProps {\n children: React.ReactNode\n /** Current animation step (0 = no animations shown yet) */\n currentStep: number\n /** Total animation steps declared in slide config */\n totalSteps: number\n /** When true, show all animations regardless of currentStep (for backward navigation) */\n showAllAnimations?: boolean\n}\n\n/**\n * Provides animation context to child components.\n *\n * The totalSteps is now passed from parent (declared in slide config)\n * rather than discovered at runtime, eliminating race conditions.\n */\nexport function AnimationProvider({\n children,\n currentStep,\n totalSteps,\n showAllAnimations = false\n}: AnimationProviderProps) {\n const value = useMemo(\n () => ({\n currentStep,\n totalSteps,\n showAllAnimations\n }),\n [currentStep, totalSteps, showAllAnimations]\n )\n\n return <AnimationContext.Provider value={value}>{children}</AnimationContext.Provider>\n}\n\nexport function useAnimationContext() {\n return useContext(AnimationContext)\n}\n","import { motion, Variants } from \"framer-motion\"\n\nimport {\n ELEMENT_SLIDE_DISTANCE,\n SPRING_SNAPPY,\n STAGGER_DELAY,\n STEP_ANIMATION_DURATION\n} from \"./animation-config\"\nimport { useAnimationContext } from \"./animation-context\"\n\n// =============================================================================\n// ANIMATION TYPES & VARIANTS\n// =============================================================================\n\nexport type AnimationType =\n | \"fade\"\n | \"slide-up\"\n | \"slide-down\"\n | \"slide-left\"\n | \"slide-right\"\n | \"scale\"\n\nconst animationVariants: Record<AnimationType, Variants> = {\n fade: {\n hidden: { opacity: 0 },\n visible: { opacity: 1 }\n },\n \"slide-up\": {\n hidden: { opacity: 0, y: ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, y: 0 }\n },\n \"slide-down\": {\n hidden: { opacity: 0, y: -ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, y: 0 }\n },\n \"slide-left\": {\n hidden: { opacity: 0, x: ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, x: 0 }\n },\n \"slide-right\": {\n hidden: { opacity: 0, x: -ELEMENT_SLIDE_DISTANCE },\n visible: { opacity: 1, x: 0 }\n },\n scale: {\n hidden: { opacity: 0, scale: 0.8 },\n visible: { opacity: 1, scale: 1 }\n }\n}\n\ninterface AnimatedProps {\n /** Which step reveals this content (1-indexed) */\n step: number\n /** Animation type */\n animation?: AnimationType\n /** Animation duration in seconds */\n duration?: number\n /** Delay after trigger in seconds */\n delay?: number\n /** Custom className */\n className?: string\n children: React.ReactNode\n}\n\n/**\n * Animated element that appears at a specific animation step.\n *\n * The step count is now declared in slide config rather than discovered\n * at runtime, so this component simply consumes the context without\n * needing to register itself.\n */\nexport function Animated({\n step,\n animation = \"slide-up\",\n duration = STEP_ANIMATION_DURATION,\n delay = 0,\n className,\n children\n}: AnimatedProps) {\n const { currentStep, showAllAnimations } = useAnimationContext()\n\n // Show all animations when navigating backward, otherwise check step\n const isVisible = showAllAnimations || currentStep >= step\n\n return (\n <motion.div\n initial=\"hidden\"\n animate={isVisible ? \"visible\" : \"hidden\"}\n variants={animationVariants[animation]}\n transition={{\n ...SPRING_SNAPPY,\n duration,\n delay: isVisible ? delay : 0\n }}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n/**\n * Wrapper for staggering multiple children.\n * Each direct child will be animated in sequence.\n */\ninterface AnimatedGroupProps {\n /** Starting step for the first child */\n startStep: number\n /** Animation type for all children */\n animation?: AnimationType\n /** Delay between each child in seconds */\n staggerDelay?: number\n className?: string\n children: React.ReactNode\n}\n\nexport function AnimatedGroup({\n startStep,\n animation = \"slide-up\",\n staggerDelay = STAGGER_DELAY,\n className,\n children\n}: AnimatedGroupProps) {\n const { currentStep, showAllAnimations } = useAnimationContext()\n\n const childArray = Array.isArray(children) ? children : [children]\n\n // Show all animations when navigating backward, otherwise check step\n const isVisible = showAllAnimations || currentStep >= startStep\n\n const containerVariants: Variants = {\n hidden: {},\n visible: {\n transition: {\n staggerChildren: staggerDelay\n }\n }\n }\n\n return (\n <motion.div\n initial=\"hidden\"\n animate={isVisible ? \"visible\" : \"hidden\"}\n variants={containerVariants}\n className={className}\n >\n {childArray.map((child, index) => (\n <motion.div key={index} variants={animationVariants[animation]}>\n {child}\n </motion.div>\n ))}\n </motion.div>\n )\n}\n","/**\n * Slide transition variants for the slide deck framework.\n * These define how slides enter and exit during navigation.\n */\n\nimport type { Variants } from \"framer-motion\"\n\nimport {\n EASE_MORPH,\n MORPH_DURATION,\n SLIDE_DISTANCE,\n SLIDE_TRANSITION,\n SLIDE_TRANSITION_DURATION\n} from \"./animation-config\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type SlideTransitionType =\n | \"fade\"\n | \"slide-left\"\n | \"slide-right\"\n | \"slide-up\"\n | \"slide-down\"\n | \"zoom\"\n | \"zoom-fade\"\n | \"morph\"\n | \"none\"\n\nexport interface SlideTransitionConfig {\n /** The transition type */\n type: SlideTransitionType\n /** Optional custom duration (overrides default) */\n duration?: number\n /** Whether to use directional transitions based on navigation direction */\n directional?: boolean\n}\n\n// =============================================================================\n// STATIC VARIANTS (non-directional)\n// =============================================================================\n\nconst fadeVariants: Variants = {\n enter: { opacity: 0 },\n center: { opacity: 1 },\n exit: { opacity: 0 }\n}\n\nconst slideLeftVariants: Variants = {\n enter: { x: SLIDE_DISTANCE, opacity: 0 },\n center: { x: 0, opacity: 1 },\n exit: { x: -SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst slideRightVariants: Variants = {\n enter: { x: -SLIDE_DISTANCE, opacity: 0 },\n center: { x: 0, opacity: 1 },\n exit: { x: SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst slideUpVariants: Variants = {\n enter: { y: SLIDE_DISTANCE, opacity: 0 },\n center: { y: 0, opacity: 1 },\n exit: { y: -SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst slideDownVariants: Variants = {\n enter: { y: -SLIDE_DISTANCE, opacity: 0 },\n center: { y: 0, opacity: 1 },\n exit: { y: SLIDE_DISTANCE, opacity: 0 }\n}\n\nconst zoomVariants: Variants = {\n enter: { scale: 0.8, opacity: 0 },\n center: { scale: 1, opacity: 1 },\n exit: { scale: 1.2, opacity: 0 }\n}\n\nconst zoomFadeVariants: Variants = {\n enter: { scale: 0.95, opacity: 0 },\n center: { scale: 1, opacity: 1 },\n exit: { scale: 1.05, opacity: 0 }\n}\n\nconst morphVariants: Variants = {\n enter: {\n opacity: 0,\n zIndex: 1\n },\n center: {\n opacity: 1,\n zIndex: 1,\n transition: {\n opacity: { delay: 0.05, duration: 0.25 }\n }\n },\n exit: {\n opacity: 0,\n zIndex: 0,\n transition: {\n opacity: { duration: MORPH_DURATION, ease: EASE_MORPH }\n }\n }\n}\n\nconst noneVariants: Variants = {\n enter: {},\n center: {},\n exit: {}\n}\n\n// =============================================================================\n// VARIANT REGISTRY\n// =============================================================================\n\nexport const SLIDE_VARIANTS: Record<SlideTransitionType, Variants> = {\n fade: fadeVariants,\n \"slide-left\": slideLeftVariants,\n \"slide-right\": slideRightVariants,\n \"slide-up\": slideUpVariants,\n \"slide-down\": slideDownVariants,\n zoom: zoomVariants,\n \"zoom-fade\": zoomFadeVariants,\n morph: morphVariants,\n none: noneVariants\n}\n\n// =============================================================================\n// DIRECTIONAL VARIANTS (based on navigation direction)\n// =============================================================================\n\nexport function createDirectionalVariants(axis: \"x\" | \"y\" = \"x\"): (direction: number) => Variants {\n return (direction: number) => ({\n enter: {\n [axis]: direction > 0 ? SLIDE_DISTANCE : -SLIDE_DISTANCE,\n opacity: 0\n },\n center: {\n [axis]: 0,\n opacity: 1\n },\n exit: {\n [axis]: direction < 0 ? SLIDE_DISTANCE : -SLIDE_DISTANCE,\n opacity: 0\n }\n })\n}\n\n/** Horizontal directional slide (left/right based on direction) */\nexport const directionalSlideX = createDirectionalVariants(\"x\")\n\n/** Vertical directional slide (up/down based on direction) */\nexport const directionalSlideY = createDirectionalVariants(\"y\")\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\nexport function getSlideVariants(\n config: SlideTransitionConfig | SlideTransitionType,\n direction: number = 1\n): Variants {\n const type = typeof config === \"string\" ? config : config.type\n const directional = typeof config === \"object\" ? config.directional : false\n\n if (directional && (type === \"slide-left\" || type === \"slide-right\")) {\n return directionalSlideX(direction)\n }\n\n if (directional && (type === \"slide-up\" || type === \"slide-down\")) {\n return directionalSlideY(direction)\n }\n\n return SLIDE_VARIANTS[type]\n}\n\nexport function getSlideTransition(config?: SlideTransitionConfig | SlideTransitionType): {\n duration: number\n ease: typeof SLIDE_TRANSITION.ease\n} {\n if (!config) return SLIDE_TRANSITION\n\n const type = typeof config === \"string\" ? config : config.type\n\n const defaultDuration = type === \"morph\" ? MORPH_DURATION : SLIDE_TRANSITION_DURATION\n\n const duration = typeof config === \"object\" && config.duration ? config.duration : defaultDuration\n\n return {\n ...SLIDE_TRANSITION,\n duration\n }\n}\n\n// =============================================================================\n// DEFAULT EXPORT\n// =============================================================================\n\nexport const DEFAULT_SLIDE_TRANSITION: SlideTransitionType = \"fade\"\n","import type { Transition } from \"framer-motion\"\n\nimport { motion } from \"framer-motion\"\n\nimport { MORPH_TRANSITION } from \"./animation-config\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface MorphProps {\n layoutId: string\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\ninterface MorphGroupProps {\n groupId: string\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\n// =============================================================================\n// MORPH COMPONENT\n// =============================================================================\n\n/**\n * Wrapper component that enables morph/shared-layout animations between slides.\n *\n * Usage:\n * ```tsx\n * // Slide 1 - Large version\n * <Morph layoutId=\"hero-title\">\n * <h1 className=\"text-6xl\">Title</h1>\n * </Morph>\n *\n * // Slide 2 - Small version (same layoutId = morphs between them)\n * <Morph layoutId=\"hero-title\">\n * <h1 className=\"text-2xl\">Title</h1>\n * </Morph>\n * ```\n */\nexport function Morph({\n layoutId,\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphProps) {\n return (\n <motion.div\n layout\n layoutId={layoutId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n// =============================================================================\n// MORPH GROUP COMPONENT\n// =============================================================================\n\nexport function MorphGroup({\n groupId,\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphGroupProps) {\n return (\n <motion.div\n layout\n layoutId={groupId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n// =============================================================================\n// MORPH ITEM (for use within MorphGroup pattern)\n// =============================================================================\n\ninterface MorphItemProps {\n id: string\n prefix?: string\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\nexport function MorphItem({\n id,\n prefix,\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphItemProps) {\n const layoutId = prefix ? `${prefix}-${id}` : id\n\n return (\n <motion.div\n layout\n layoutId={layoutId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </motion.div>\n )\n}\n\n// =============================================================================\n// MORPH TEXT (specialized for text that changes size)\n// =============================================================================\n\ninterface MorphTextProps {\n layoutId: string\n as?: \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"p\" | \"span\"\n transition?: Transition\n className?: string\n children: React.ReactNode\n}\n\nexport function MorphText({\n layoutId,\n as: Component = \"span\",\n transition = MORPH_TRANSITION,\n className,\n children\n}: MorphTextProps) {\n const MotionComponent = motion[Component]\n\n return (\n <MotionComponent\n layout\n layoutId={layoutId}\n initial={false}\n transition={transition}\n className={className}\n >\n {children}\n </MotionComponent>\n )\n}\n","import { useCallback, useEffect, useState } from \"react\"\n\nimport type { NavigationDirection, SlideConfig } from \"./types\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ntype NavigationStatus = \"idle\" | \"transitioning\"\n\ntype QueuedAction = \"advance\" | \"goBack\" | null\n\ninterface NavigationState {\n status: NavigationStatus\n direction: NavigationDirection\n}\n\nexport interface UseSlideNavigationOptions {\n slides: SlideConfig[]\n initialSlide?: number\n onSlideChange?: (slideIndex: number) => void\n}\n\nexport interface UseSlideNavigationReturn {\n currentSlide: number\n animationStep: number\n totalSteps: number\n direction: NavigationDirection\n isTransitioning: boolean\n showAllAnimations: boolean\n advance: () => void\n goBack: () => void\n goToSlide: (index: number) => void\n onTransitionComplete: () => void\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\nexport function useSlideNavigation({\n slides,\n initialSlide = 0,\n onSlideChange\n}: UseSlideNavigationOptions): UseSlideNavigationReturn {\n const [currentSlide, setCurrentSlide] = useState(initialSlide)\n const [animationStep, setAnimationStep] = useState(0)\n\n const [navState, setNavState] = useState<NavigationState>({\n status: \"idle\",\n direction: 0\n })\n\n const [queuedAction, setQueuedAction] = useState<QueuedAction>(null)\n\n const totalSteps = slides[currentSlide]?.steps ?? 0\n\n const onTransitionComplete = useCallback(() => {\n setNavState(prev => {\n if (prev.status === \"transitioning\") {\n return { status: \"idle\", direction: 0 }\n }\n return prev\n })\n }, [])\n\n const advance = useCallback(() => {\n if (navState.status === \"transitioning\") {\n setQueuedAction(\"advance\")\n return\n }\n\n const currentTotalSteps = slides[currentSlide]?.steps ?? 0\n\n if (animationStep >= currentTotalSteps) {\n const nextSlide = (currentSlide + 1) % slides.length\n setNavState({ status: \"transitioning\", direction: 1 })\n setAnimationStep(0)\n setCurrentSlide(nextSlide)\n onSlideChange?.(nextSlide)\n } else {\n setAnimationStep(prev => prev + 1)\n }\n }, [navState.status, animationStep, currentSlide, slides, onSlideChange])\n\n const goBack = useCallback(() => {\n if (navState.status === \"transitioning\") {\n setQueuedAction(\"goBack\")\n return\n }\n\n if (animationStep <= 0) {\n const prevSlide = (currentSlide - 1 + slides.length) % slides.length\n const prevSlideSteps = slides[prevSlide]?.steps ?? 0\n setNavState({ status: \"transitioning\", direction: -1 })\n setAnimationStep(prevSlideSteps)\n setCurrentSlide(prevSlide)\n onSlideChange?.(prevSlide)\n } else {\n setAnimationStep(prev => prev - 1)\n }\n }, [navState.status, animationStep, currentSlide, slides, onSlideChange])\n\n const goToSlide = useCallback(\n (index: number) => {\n if (index < 0 || index >= slides.length || index === currentSlide) {\n return\n }\n\n const direction = index > currentSlide ? 1 : -1\n setNavState({ status: \"transitioning\", direction })\n setAnimationStep(0)\n setCurrentSlide(index)\n onSlideChange?.(index)\n },\n [currentSlide, slides.length, onSlideChange]\n )\n\n useEffect(() => {\n if (navState.status === \"idle\" && queuedAction !== null) {\n setQueuedAction(null)\n if (queuedAction === \"advance\") {\n advance()\n } else if (queuedAction === \"goBack\") {\n goBack()\n }\n }\n }, [navState.status, queuedAction, advance, goBack])\n\n return {\n currentSlide,\n animationStep,\n totalSteps,\n direction: navState.direction,\n isTransitioning: navState.status !== \"idle\",\n showAllAnimations: navState.direction === -1 && navState.status === \"transitioning\",\n advance,\n goBack,\n goToSlide,\n onTransitionComplete\n }\n}\n","import { createContext, useContext, useMemo } from \"react\"\nimport type { ThemeConfig } from \"./types\"\n\nconst ThemeContext = createContext<ThemeConfig | null>(null)\n\n/**\n * Access the full theme config. Returns null outside SlideThemeProvider.\n */\nexport function useTheme(): ThemeConfig | null {\n return useContext(ThemeContext)\n}\n\nfunction buildCssOverrides(theme: ThemeConfig): React.CSSProperties {\n const style: Record<string, string> = {}\n\n if (theme.colors?.primary) style[\"--primary\"] = theme.colors.primary\n if (theme.colors?.primaryForeground) style[\"--primary-foreground\"] = theme.colors.primaryForeground\n if (theme.colors?.secondary) style[\"--secondary\"] = theme.colors.secondary\n if (theme.colors?.secondaryForeground) style[\"--secondary-foreground\"] = theme.colors.secondaryForeground\n if (theme.colors?.accent) style[\"--accent\"] = theme.colors.accent\n if (theme.colors?.accentForeground) style[\"--accent-foreground\"] = theme.colors.accentForeground\n\n if (theme.fonts?.heading) style[\"--font-heading\"] = theme.fonts.heading\n if (theme.fonts?.body) style[\"--font-body\"] = theme.fonts.body\n\n return style as React.CSSProperties\n}\n\ninterface SlideThemeProviderProps {\n theme: ThemeConfig\n children: React.ReactNode\n}\n\n/**\n * Provides the full theme to all descendants.\n * Injects CSS variable overrides via inline style.\n */\nexport function SlideThemeProvider({ theme, children }: SlideThemeProviderProps) {\n const cssOverrides = useMemo(() => buildCssOverrides(theme), [theme])\n\n return (\n <ThemeContext.Provider value={theme}>\n <div style={cssOverrides} className=\"contents\">\n {children}\n </div>\n </ThemeContext.Provider>\n )\n}\n","import { useTheme } from \"../theme-context\"\n\ninterface SlideFooterProps {\n slideNumber: number\n totalSlides: number\n /** Use light text/logo for dark slide backgrounds */\n variant?: \"default\" | \"light\"\n}\n\nexport function SlideFooter({ slideNumber, totalSlides, variant = \"default\" }: SlideFooterProps) {\n const theme = useTheme()\n if (!theme) return null\n\n const logoUrl = variant === \"light\"\n ? (theme.logo?.fullLight ?? theme.logo?.full)\n : theme.logo?.full\n\n const textClass = variant === \"light\"\n ? \"text-white/70\"\n : \"text-muted-foreground\"\n\n const nameClass = variant === \"light\"\n ? \"text-white font-semibold\"\n : \"text-foreground font-semibold\"\n\n return (\n <div className={`mt-4 flex shrink-0 items-center justify-between text-sm ${textClass}`}>\n <div className={`flex items-center gap-3 tracking-tight ${nameClass}`}>\n {logoUrl && (\n <img\n src={logoUrl}\n alt={`${theme.name} Logo`}\n className=\"h-8 w-auto\"\n />\n )}\n <span className=\"text-lg\">{theme.name}</span>\n </div>\n <div className=\"font-mono\">\n {slideNumber} / {totalSlides}\n </div>\n </div>\n )\n}\n","import { AnimatePresence, motion } from \"framer-motion\"\n\nimport type { SlideTransitionType } from \"./transitions\"\nimport type { NavigationDirection, SlideConfig } from \"./types\"\n\nimport { SLIDE_TRANSITION } from \"./animation-config\"\nimport { AnimationProvider } from \"./animation-context\"\nimport { SlideErrorBoundary } from \"./slide-error-boundary\"\nimport { DEFAULT_SLIDE_TRANSITION, getSlideVariants } from \"./transitions\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface SlideRendererProps {\n slides: SlideConfig[]\n currentSlide: number\n animationStep: number\n totalSteps: number\n direction: NavigationDirection\n showAllAnimations: boolean\n transition?: SlideTransitionType\n directionalTransition?: boolean\n onTransitionComplete: () => void\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\n/**\n * Renders a single slide with animated transitions.\n * Extracted from SlideDeck so it can be reused in SlideEmbed and other contexts.\n */\nexport function SlideRenderer({\n slides,\n currentSlide,\n animationStep,\n totalSteps,\n direction,\n showAllAnimations,\n transition,\n directionalTransition,\n onTransitionComplete\n}: SlideRendererProps) {\n const currentSlideTransition = slides[currentSlide]?.transition\n const transitionType = currentSlideTransition ?? transition ?? DEFAULT_SLIDE_TRANSITION\n const isDirectional = directionalTransition ?? false\n\n const slideVariants = getSlideVariants(\n { type: transitionType, directional: isDirectional },\n direction\n )\n\n const CurrentSlideComponent = slides[currentSlide]!.component\n\n return (\n <AnimatePresence initial={false}>\n <motion.div\n key={currentSlide}\n variants={slideVariants}\n initial=\"enter\"\n animate=\"center\"\n exit=\"exit\"\n transition={SLIDE_TRANSITION}\n onAnimationComplete={definition => {\n if (definition === \"center\") {\n onTransitionComplete()\n }\n }}\n className=\"absolute inset-0 h-full w-full\"\n >\n <AnimationProvider\n currentStep={animationStep}\n totalSteps={totalSteps}\n showAllAnimations={showAllAnimations}\n >\n <SlideErrorBoundary\n slideIndex={currentSlide}\n slideTitle={slides[currentSlide]?.title}\n >\n <CurrentSlideComponent\n slideNumber={currentSlide + 1}\n totalSlides={slides.length}\n />\n </SlideErrorBoundary>\n </AnimationProvider>\n </motion.div>\n </AnimatePresence>\n )\n}\n","import React from \"react\"\n\ninterface SlideErrorBoundaryProps {\n slideIndex: number\n slideTitle?: string\n children: React.ReactNode\n}\n\ninterface SlideErrorBoundaryState {\n hasError: boolean\n error: Error | null\n}\n\nexport class SlideErrorBoundary extends React.Component<\n SlideErrorBoundaryProps,\n SlideErrorBoundaryState\n> {\n state: SlideErrorBoundaryState = { hasError: false, error: null }\n\n static getDerivedStateFromError(error: Error) {\n return { hasError: true, error }\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n console.error(\n `[PromptSlide] Slide ${this.props.slideIndex + 1}${this.props.slideTitle ? ` (\"${this.props.slideTitle}\")` : \"\"} crashed:`,\n error,\n errorInfo\n )\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <div className=\"flex h-full w-full flex-col items-center justify-center bg-red-950/20 p-12\">\n <div className=\"mb-4 text-lg font-semibold text-red-400\">\n Slide {this.props.slideIndex + 1} Error\n {this.props.slideTitle && (\n <span className=\"ml-2 font-normal text-red-400/70\">({this.props.slideTitle})</span>\n )}\n </div>\n <div className=\"max-w-2xl text-center font-mono text-sm break-words text-red-300/80\">\n {this.state.error?.message ?? \"Unknown error\"}\n </div>\n </div>\n )\n }\n return this.props.children\n }\n}\n","import { useCallback, useEffect, useState } from \"react\"\n\nimport type { SlideTransitionType } from \"./transitions\"\nimport type { SlideConfig } from \"./types\"\n\nimport { SLIDE_DIMENSIONS } from \"./animation-config\"\nimport { SlideRenderer } from \"./slide-renderer\"\nimport { useSlideNavigation } from \"./use-slide-navigation\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ninterface SlideEmbedProps {\n slides: SlideConfig[]\n transition?: SlideTransitionType\n directionalTransition?: boolean\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\n/**\n * Headless slide viewer controlled via window.postMessage.\n * Designed for embedding in an iframe (e.g. the registry editor preview).\n *\n * Inbound messages (parent → embed):\n * { type: \"navigate\", data: { slide: number } }\n * { type: \"advance\" }\n * { type: \"goBack\" }\n *\n * Outbound messages (embed → parent):\n * { type: \"slideReady\" }\n * { type: \"slideState\", data: { currentSlide, totalSlides, animationStep, totalSteps, titles } }\n * { type: \"hmrUpdate\" }\n */\nexport function SlideEmbed({ slides, transition, directionalTransition }: SlideEmbedProps) {\n const [scale, setScale] = useState(1)\n\n const {\n currentSlide,\n animationStep,\n totalSteps,\n direction,\n showAllAnimations,\n advance,\n goBack,\n goToSlide,\n onTransitionComplete\n } = useSlideNavigation({ slides })\n\n // Post slide state to parent whenever it changes\n useEffect(() => {\n const state = {\n currentSlide,\n totalSlides: slides.length,\n animationStep,\n totalSteps,\n titles: slides.map(s => s.title || \"\")\n }\n window.parent.postMessage({ type: \"slideState\", data: state }, \"*\")\n }, [currentSlide, animationStep, totalSteps, slides])\n\n // Signal readiness on mount\n useEffect(() => {\n window.parent.postMessage({ type: \"slideReady\" }, \"*\")\n }, [])\n\n // Listen for Vite HMR updates\n useEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const hot = (import.meta as any).hot as { on: (event: string, cb: () => void) => void } | undefined\n if (hot) {\n hot.on(\"vite:afterUpdate\", () => {\n window.parent.postMessage({ type: \"hmrUpdate\" }, \"*\")\n })\n }\n }, [])\n\n // Listen for inbound messages from parent\n const handleMessage = useCallback(\n (event: MessageEvent) => {\n const { type, data } = event.data || {}\n switch (type) {\n case \"navigate\":\n if (typeof data?.slide === \"number\") goToSlide(data.slide)\n break\n case \"advance\":\n advance()\n break\n case \"goBack\":\n goBack()\n break\n }\n },\n [advance, goBack, goToSlide]\n )\n\n useEffect(() => {\n window.addEventListener(\"message\", handleMessage)\n return () => window.removeEventListener(\"message\", handleMessage)\n }, [handleMessage])\n\n // Scale to fill viewport\n useEffect(() => {\n const calculateScale = () => {\n const scaleX = window.innerWidth / SLIDE_DIMENSIONS.width\n const scaleY = window.innerHeight / SLIDE_DIMENSIONS.height\n setScale(Math.min(scaleX, scaleY))\n }\n\n calculateScale()\n window.addEventListener(\"resize\", calculateScale)\n return () => window.removeEventListener(\"resize\", calculateScale)\n }, [])\n\n return (\n <div className=\"flex h-screen w-screen items-center justify-center overflow-hidden bg-black\">\n <div\n className=\"relative overflow-hidden bg-black\"\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n transform: `scale(${scale})`,\n transformOrigin: \"center center\"\n }}\n >\n <SlideRenderer\n slides={slides}\n currentSlide={currentSlide}\n animationStep={animationStep}\n totalSteps={totalSteps}\n direction={direction}\n showAllAnimations={showAllAnimations}\n transition={transition}\n directionalTransition={directionalTransition}\n onTransitionComplete={onTransitionComplete}\n />\n </div>\n </div>\n )\n}\n","import { LayoutGroup } from \"framer-motion\"\nimport { ChevronLeft, ChevronRight, Download, Grid3X3, List, Maximize, Monitor } from \"lucide-react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\nimport type { SlideTransitionType } from \"./transitions\"\nimport type { SlideConfig } from \"./types\"\n\nimport { SLIDE_DIMENSIONS } from \"./animation-config\"\nimport { AnimationProvider } from \"./animation-context\"\nimport { SlideErrorBoundary } from \"./slide-error-boundary\"\nimport { SlideRenderer } from \"./slide-renderer\"\nimport { useSlideNavigation } from \"./use-slide-navigation\"\nimport { cn } from \"./utils\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\ntype ViewMode = \"slide\" | \"list\" | \"grid\"\n\ninterface SlideDeckProps {\n slides: SlideConfig[]\n transition?: SlideTransitionType\n directionalTransition?: boolean\n}\n\n// =============================================================================\n// EXPORT VIEW (for Playwright screenshot capture)\n// =============================================================================\n\nfunction SlideExportView({ slides, slideIndex }: { slides: SlideConfig[]; slideIndex: number }) {\n const [ready, setReady] = useState(false)\n const clampedIndex = Math.max(0, Math.min(slideIndex, slides.length - 1))\n const slideConfig = slides[clampedIndex]!\n const SlideComponent = slideConfig.component\n\n useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <div\n data-export-ready={ready ? \"true\" : undefined}\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n overflow: \"hidden\",\n position: \"relative\",\n background: \"black\"\n }}\n >\n <AnimationProvider\n currentStep={slideConfig.steps}\n totalSteps={slideConfig.steps}\n showAllAnimations={true}\n >\n <SlideErrorBoundary slideIndex={clampedIndex} slideTitle={slideConfig.title}>\n <SlideComponent slideNumber={clampedIndex + 1} totalSlides={slides.length} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n )\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nexport function SlideDeck({ slides, transition, directionalTransition }: SlideDeckProps) {\n // Check for export mode via URL params\n const [exportParams] = useState(() => {\n if (typeof window === \"undefined\") return null\n const params = new URLSearchParams(window.location.search)\n if (params.get(\"export\") !== \"true\") return null\n return { slideIndex: parseInt(params.get(\"slide\") || \"0\", 10) }\n })\n\n if (exportParams) {\n return <SlideExportView slides={slides} slideIndex={exportParams.slideIndex} />\n }\n\n const [viewMode, setViewMode] = useState<ViewMode>(\"slide\")\n const [isPresentationMode, setIsPresentationMode] = useState(false)\n const [scale, setScale] = useState(1)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const {\n currentSlide,\n animationStep,\n totalSteps,\n direction,\n showAllAnimations,\n advance,\n goBack,\n goToSlide,\n onTransitionComplete\n } = useSlideNavigation({\n slides\n })\n\n const togglePresentationMode = useCallback(async () => {\n if (!document.fullscreenElement) {\n await document.documentElement.requestFullscreen()\n } else {\n await document.exitFullscreen()\n }\n }, [])\n\n // Listen for fullscreen changes\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsPresentationMode(!!document.fullscreenElement)\n }\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange)\n return () => document.removeEventListener(\"fullscreenchange\", handleFullscreenChange)\n }, [])\n\n // Calculate scale factor for presentation mode\n useEffect(() => {\n const calculateScale = () => {\n if (!isPresentationMode) {\n setScale(1)\n return\n }\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n const scaleX = viewportWidth / SLIDE_DIMENSIONS.width\n const scaleY = viewportHeight / SLIDE_DIMENSIONS.height\n setScale(Math.min(scaleX, scaleY))\n }\n\n calculateScale()\n window.addEventListener(\"resize\", calculateScale)\n return () => window.removeEventListener(\"resize\", calculateScale)\n }, [isPresentationMode])\n\n const handleExportPdf = () => {\n const previousMode = viewMode\n setViewMode(\"list\")\n\n setTimeout(() => {\n const handleAfterPrint = () => {\n setViewMode(previousMode)\n window.removeEventListener(\"afterprint\", handleAfterPrint)\n }\n window.addEventListener(\"afterprint\", handleAfterPrint)\n window.print()\n }, 100)\n }\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"f\" || e.key === \"F\") {\n togglePresentationMode()\n return\n }\n\n // G for grid view toggle\n if (e.key === \"g\" || e.key === \"G\") {\n setViewMode(prev => (prev === \"grid\" ? \"slide\" : \"grid\"))\n return\n }\n\n if (viewMode !== \"slide\") return\n\n if (e.key === \"ArrowRight\" || e.key === \" \") {\n e.preventDefault()\n advance()\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault()\n goBack()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [advance, goBack, viewMode, togglePresentationMode])\n\n return (\n <div className=\"min-h-screen w-full bg-neutral-950 text-foreground\">\n <style>{`\n @media print {\n @page {\n size: 1920px 1080px;\n margin: 0;\n }\n html,\n body {\n width: 100%;\n height: 100%;\n margin: 0 !important;\n padding: 0 !important;\n overflow: visible !important;\n }\n body {\n print-color-adjust: exact;\n -webkit-print-color-adjust: exact;\n background: transparent !important;\n }\n }\n `}</style>\n\n {/* Toolbar */}\n <div\n className={cn(\n \"fixed top-4 right-4 z-50 flex gap-1 rounded-lg border border-neutral-800 bg-neutral-950/90 p-1 backdrop-blur-sm print:hidden\",\n isPresentationMode && \"hidden\"\n )}\n >\n <button\n onClick={() => setViewMode(\"slide\")}\n className={cn(\n \"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\",\n viewMode === \"slide\" && \"bg-neutral-800 text-white\"\n )}\n title=\"Presentation View\"\n >\n <Monitor className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode(\"list\")}\n className={cn(\n \"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\",\n viewMode === \"list\" && \"bg-neutral-800 text-white\"\n )}\n title=\"List View\"\n >\n <List className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode(\"grid\")}\n className={cn(\n \"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\",\n viewMode === \"grid\" && \"bg-neutral-800 text-white\"\n )}\n title=\"Grid View\"\n >\n <Grid3X3 className=\"h-4 w-4\" />\n </button>\n\n <div className=\"mx-1 w-px bg-neutral-800\" />\n\n <button\n onClick={handleExportPdf}\n className=\"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\"\n title=\"Download PDF\"\n >\n <Download className=\"h-4 w-4\" />\n </button>\n <button\n onClick={togglePresentationMode}\n className=\"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\"\n title=\"Present (F)\"\n >\n <Maximize className=\"h-4 w-4\" />\n </button>\n </div>\n\n {/* Slide View */}\n {viewMode === \"slide\" && (\n <div\n ref={containerRef}\n role=\"presentation\"\n tabIndex={isPresentationMode ? 0 : undefined}\n className={cn(\n \"flex h-screen w-full flex-col items-center justify-center overflow-hidden print:hidden\",\n isPresentationMode ? \"bg-black p-0\" : \"p-4 md:p-8\"\n )}\n onClick={isPresentationMode ? advance : undefined}\n onKeyDown={\n isPresentationMode\n ? e => {\n if (e.key === \"Enter\" || e.key === \" \") advance()\n }\n : undefined\n }\n >\n <LayoutGroup id=\"slide-deck\">\n {isPresentationMode ? (\n <div\n className=\"pointer-events-none relative overflow-hidden bg-black\"\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n transform: `scale(${scale})`,\n transformOrigin: \"center center\"\n }}\n >\n <SlideRenderer\n slides={slides}\n currentSlide={currentSlide}\n animationStep={animationStep}\n totalSteps={totalSteps}\n direction={direction}\n showAllAnimations={showAllAnimations}\n transition={transition}\n directionalTransition={directionalTransition}\n onTransitionComplete={onTransitionComplete}\n />\n </div>\n ) : (\n <div className=\"relative aspect-video w-full max-w-7xl overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-2xl\">\n <SlideRenderer\n slides={slides}\n currentSlide={currentSlide}\n animationStep={animationStep}\n totalSteps={totalSteps}\n direction={direction}\n showAllAnimations={showAllAnimations}\n transition={transition}\n directionalTransition={directionalTransition}\n onTransitionComplete={onTransitionComplete}\n />\n </div>\n )}\n </LayoutGroup>\n\n {/* Navigation Controls */}\n {!isPresentationMode && (\n <div className=\"mt-6 flex items-center gap-4\">\n <button\n onClick={goBack}\n className=\"rounded-full border border-neutral-800 bg-black/50 p-2 text-neutral-400 backdrop-blur-sm transition-colors hover:bg-neutral-900 hover:text-white\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </button>\n <div className=\"flex min-w-[4rem] flex-col items-center\">\n <span className=\"font-mono text-sm text-neutral-500\">\n {currentSlide + 1} / {slides.length}\n </span>\n {slides[currentSlide]?.title && (\n <span className=\"mt-0.5 text-xs text-neutral-600\">\n {slides[currentSlide].title}\n </span>\n )}\n </div>\n <button\n onClick={advance}\n className=\"rounded-full border border-neutral-800 bg-black/50 p-2 text-neutral-400 backdrop-blur-sm transition-colors hover:bg-neutral-900 hover:text-white\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </div>\n )}\n </div>\n )}\n\n {/* Grid View */}\n {viewMode === \"grid\" && (\n <div className=\"mx-auto max-w-7xl p-8 pt-16 print:hidden\">\n <div className=\"grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4\">\n {slides.map((slideConfig, index) => {\n const SlideComponent = slideConfig.component\n const prevSection = index > 0 ? slides[index - 1]?.section : undefined\n const showSectionHeader = slideConfig.section && slideConfig.section !== prevSection\n\n return (\n <div key={index} className={showSectionHeader ? \"col-span-full\" : undefined}>\n {showSectionHeader && (\n <h3 className=\"mt-4 mb-3 text-xs font-bold tracking-[0.2em] text-neutral-500 uppercase first:mt-0\">\n {slideConfig.section}\n </h3>\n )}\n <button\n onClick={() => {\n goToSlide(index)\n setViewMode(\"slide\")\n }}\n className=\"group relative aspect-video w-full overflow-hidden rounded-lg border border-neutral-800 bg-black shadow-sm transition-all hover:border-primary hover:shadow-lg hover:shadow-primary/10\"\n >\n <div\n className=\"h-full w-full origin-top-left scale-[0.25]\"\n style={{ width: \"400%\", height: \"400%\" }}\n >\n <AnimationProvider\n currentStep={slideConfig.steps}\n totalSteps={slideConfig.steps}\n showAllAnimations={true}\n >\n <SlideErrorBoundary slideIndex={index} slideTitle={slideConfig.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={slides.length} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n <div className=\"absolute inset-0 bg-black/0 transition-colors group-hover:bg-black/20\" />\n <div className=\"absolute bottom-2 left-2 rounded bg-black/70 px-2 py-1 text-xs font-medium text-white\">\n {slideConfig.title ? `${index + 1}. ${slideConfig.title}` : index + 1}\n </div>\n </button>\n </div>\n )\n })}\n </div>\n </div>\n )}\n\n {/* List View */}\n <div\n className={cn(\n \"mx-auto max-w-7xl p-8 pt-16\",\n \"print:m-0 print:block print:max-w-none print:p-0\",\n viewMode === \"list\" ? \"block\" : \"hidden print:block\"\n )}\n >\n <div className=\"grid grid-cols-1 gap-8 print:block\">\n {slides.map((slideConfig, index) => {\n const SlideComponent = slideConfig.component\n return (\n <div\n key={index}\n className=\"aspect-video w-full overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-sm print:relative print:m-0 print:h-[1080px] print:w-[1920px] print:break-after-page print:overflow-hidden print:rounded-none print:border-0 print:shadow-none\"\n >\n <div className=\"h-full w-full print:h-[720px] print:w-[1280px] print:origin-top-left print:scale-[1.5]\">\n <AnimationProvider\n currentStep={slideConfig.steps}\n totalSteps={slideConfig.steps}\n showAllAnimations={true}\n >\n <SlideErrorBoundary slideIndex={index} slideTitle={slideConfig.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={slides.length} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n </div>\n )\n}\n","import type { ClassValue } from \"clsx\"\n\nimport { clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":"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","names":["jsx","motion","jsx","motion","createContext","useContext","useMemo","jsx","jsx","motion","jsx","jsxs","jsx","motion","useCallback","useEffect","useState","jsx","useState","useEffect","useCallback","useCallback","useEffect","useState","jsx","jsxs","useState","useEffect","useCallback"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptslide",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "CLI and slide engine for PromptSlide presentations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,28 +15,7 @@ const __filename = fileURLToPath(import.meta.url)
15
15
  const __dirname = dirname(__filename)
16
16
  const CLI_ROOT = join(__dirname, "..", "..")
17
17
  const TEMPLATE_DIR = join(CLI_ROOT, "templates", "default")
18
-
19
- /**
20
- * Detect if we're running from a local dev/linked install (monorepo).
21
- * If so, return absolute paths to the local packages so scaffolded
22
- * projects can resolve them without npm publish.
23
- */
24
- function getLocalPackagePaths() {
25
- try {
26
- const monoRoot = resolve(CLI_ROOT, "..", "..")
27
- const cliPkg = join(monoRoot, "packages", "cli", "package.json")
28
-
29
- if (existsSync(cliPkg)) {
30
- const pkg = JSON.parse(readFileSync(cliPkg, "utf-8"))
31
- if (pkg.name === "promptslide") {
32
- return {
33
- cli: resolve(monoRoot, "packages", "cli")
34
- }
35
- }
36
- }
37
- } catch {}
38
- return null
39
- }
18
+ const CLI_VERSION = JSON.parse(readFileSync(join(CLI_ROOT, "package.json"), "utf-8")).version
40
19
 
41
20
  function titleCase(slug) {
42
21
  return slug.replace(/[-_]/g, " ").replace(/\b\w/g, c => c.toUpperCase())
@@ -63,7 +42,7 @@ export async function create(args) {
63
42
  const useDefaults = args.includes("--yes") || args.includes("-y")
64
43
  const fromIdx = args.findIndex(a => a === "--from")
65
44
  const fromSlug = fromIdx >= 0 ? args[fromIdx + 1] : null
66
- const filteredArgs = args.filter((a, i) => a !== "--yes" && a !== "-y" && a !== "--from" && i !== fromIdx + 1)
45
+ const filteredArgs = args.filter((a, i) => a !== "--yes" && a !== "-y" && a !== "--from" && !(fromIdx >= 0 && i === fromIdx + 1))
67
46
 
68
47
  // 1. Parse directory name from args or prompt
69
48
  let dirName = filteredArgs[0]
@@ -142,7 +121,7 @@ export async function create(args) {
142
121
  const replacements = [
143
122
  {
144
123
  path: join(targetDir, "package.json"),
145
- values: { "{{PROJECT_SLUG}}": dirName, "{{PROJECT_NAME}}": projectName }
124
+ values: { "{{PROJECT_SLUG}}": dirName, "{{PROJECT_NAME}}": projectName, "{{PROMPTSLIDE_VERSION}}": `^${CLI_VERSION}` }
146
125
  },
147
126
  {
148
127
  path: join(targetDir, "src", "theme.ts"),
@@ -248,20 +227,10 @@ export async function create(args) {
248
227
  console.log()
249
228
  }
250
229
 
251
- // 7. If running from local dev, rewrite deps to use file: paths (must run after --from to not overwrite)
252
- const localPaths = getLocalPackagePaths()
253
- if (localPaths) {
254
- const pkgPath = join(targetDir, "package.json")
255
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"))
256
- pkg.dependencies["promptslide"] = `file:${localPaths.cli}`
257
- writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8")
258
- console.log(` ${dim("Local dev detected — using file: paths for packages")}`)
259
- }
260
-
261
- // 8. Generate tsconfig.json for editor support
230
+ // 7. Generate tsconfig.json for editor support
262
231
  ensureTsConfig(targetDir)
263
232
 
264
- // 9. Install PromptSlide agent skill (defaults to yes; skipped with --yes since skills CLI is interactive)
233
+ // 8. Install PromptSlide agent skill (defaults to yes; skipped with --yes since skills CLI is interactive)
265
234
  if (useDefaults) {
266
235
  console.log(` ${dim("Tip: Run")} npx skills add prompticeu/promptslide ${dim("to install the agent skill")}`)
267
236
  } else {
@@ -283,7 +252,7 @@ export async function create(args) {
283
252
  }
284
253
  }
285
254
 
286
- // 10. Success output
255
+ // 9. Success output
287
256
  console.log()
288
257
  console.log(` ${green("✓")} Created ${bold(projectName)} in ${cyan(dirName)}/`)
289
258
  console.log()
@@ -8,6 +8,9 @@ export async function studio(args) {
8
8
  const cwd = process.cwd()
9
9
  const portArg = args.find(a => a.startsWith("--port="))
10
10
  const port = portArg ? parseInt(portArg.split("=")[1], 10) : 5173
11
+ const hasHost = args.includes("--host") || args.some(a => a.startsWith("--host="))
12
+ const hostArg = args.find(a => a.startsWith("--host="))
13
+ const host = hasHost ? (hostArg ? hostArg.split("=")[1] : "0.0.0.0") : undefined
11
14
 
12
15
  ensureTsConfig(cwd)
13
16
 
@@ -18,7 +21,11 @@ export async function studio(args) {
18
21
  const config = createViteConfig({ cwd, mode: "development" })
19
22
  const server = await createServer({
20
23
  ...config,
21
- server: { port, strictPort: false }
24
+ server: {
25
+ port,
26
+ strictPort: false,
27
+ ...(host && { host, allowedHosts: true })
28
+ }
22
29
  })
23
30
 
24
31
  await server.listen()
package/src/core/index.ts CHANGED
@@ -63,6 +63,13 @@ export type { ThemeConfig } from "./types"
63
63
  // Shared Footer
64
64
  export { SlideFooter } from "./layouts/shared-footer"
65
65
 
66
+ // SlideRenderer
67
+ export { SlideRenderer } from "./slide-renderer"
68
+ export type { SlideRendererProps } from "./slide-renderer"
69
+
70
+ // SlideEmbed
71
+ export { SlideEmbed } from "./slide-embed"
72
+
66
73
  // SlideDeck
67
74
  export { SlideDeck } from "./slide-deck"
68
75
 
@@ -1,14 +1,14 @@
1
- import { AnimatePresence, LayoutGroup, motion } from "framer-motion"
1
+ import { LayoutGroup } from "framer-motion"
2
2
  import { ChevronLeft, ChevronRight, Download, Grid3X3, List, Maximize, Monitor } from "lucide-react"
3
3
  import { useCallback, useEffect, useRef, useState } from "react"
4
4
 
5
5
  import type { SlideTransitionType } from "./transitions"
6
6
  import type { SlideConfig } from "./types"
7
7
 
8
- import { SLIDE_DIMENSIONS, SLIDE_TRANSITION } from "./animation-config"
8
+ import { SLIDE_DIMENSIONS } from "./animation-config"
9
9
  import { AnimationProvider } from "./animation-context"
10
10
  import { SlideErrorBoundary } from "./slide-error-boundary"
11
- import { DEFAULT_SLIDE_TRANSITION, getSlideVariants } from "./transitions"
11
+ import { SlideRenderer } from "./slide-renderer"
12
12
  import { useSlideNavigation } from "./use-slide-navigation"
13
13
  import { cn } from "./utils"
14
14
 
@@ -177,18 +177,6 @@ export function SlideDeck({ slides, transition, directionalTransition }: SlideDe
177
177
  return () => window.removeEventListener("keydown", handleKeyDown)
178
178
  }, [advance, goBack, viewMode, togglePresentationMode])
179
179
 
180
- // Per-slide transition resolution
181
- const currentSlideTransition = slides[currentSlide]?.transition
182
- const transitionType = currentSlideTransition ?? transition ?? DEFAULT_SLIDE_TRANSITION
183
- const isDirectional = directionalTransition ?? false
184
-
185
- const slideVariants = getSlideVariants(
186
- { type: transitionType, directional: isDirectional },
187
- direction
188
- )
189
-
190
- const CurrentSlideComponent = slides[currentSlide]!.component
191
-
192
180
  return (
193
181
  <div className="min-h-screen w-full bg-neutral-950 text-foreground">
194
182
  <style>{`
@@ -299,73 +287,31 @@ export function SlideDeck({ slides, transition, directionalTransition }: SlideDe
299
287
  transformOrigin: "center center"
300
288
  }}
301
289
  >
302
- <AnimatePresence initial={false}>
303
- <motion.div
304
- key={currentSlide}
305
- variants={slideVariants}
306
- initial="enter"
307
- animate="center"
308
- exit="exit"
309
- transition={SLIDE_TRANSITION}
310
- onAnimationComplete={definition => {
311
- if (definition === "center") {
312
- onTransitionComplete()
313
- }
314
- }}
315
- className="absolute inset-0 h-full w-full"
316
- >
317
- <AnimationProvider
318
- currentStep={animationStep}
319
- totalSteps={totalSteps}
320
- showAllAnimations={showAllAnimations}
321
- >
322
- <SlideErrorBoundary
323
- slideIndex={currentSlide}
324
- slideTitle={slides[currentSlide]?.title}
325
- >
326
- <CurrentSlideComponent
327
- slideNumber={currentSlide + 1}
328
- totalSlides={slides.length}
329
- />
330
- </SlideErrorBoundary>
331
- </AnimationProvider>
332
- </motion.div>
333
- </AnimatePresence>
290
+ <SlideRenderer
291
+ slides={slides}
292
+ currentSlide={currentSlide}
293
+ animationStep={animationStep}
294
+ totalSteps={totalSteps}
295
+ direction={direction}
296
+ showAllAnimations={showAllAnimations}
297
+ transition={transition}
298
+ directionalTransition={directionalTransition}
299
+ onTransitionComplete={onTransitionComplete}
300
+ />
334
301
  </div>
335
302
  ) : (
336
303
  <div className="relative aspect-video w-full max-w-7xl overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-2xl">
337
- <AnimatePresence initial={false}>
338
- <motion.div
339
- key={currentSlide}
340
- variants={slideVariants}
341
- initial="enter"
342
- animate="center"
343
- exit="exit"
344
- transition={SLIDE_TRANSITION}
345
- onAnimationComplete={definition => {
346
- if (definition === "center") {
347
- onTransitionComplete()
348
- }
349
- }}
350
- className="absolute inset-0 h-full w-full"
351
- >
352
- <AnimationProvider
353
- currentStep={animationStep}
354
- totalSteps={totalSteps}
355
- showAllAnimations={showAllAnimations}
356
- >
357
- <SlideErrorBoundary
358
- slideIndex={currentSlide}
359
- slideTitle={slides[currentSlide]?.title}
360
- >
361
- <CurrentSlideComponent
362
- slideNumber={currentSlide + 1}
363
- totalSlides={slides.length}
364
- />
365
- </SlideErrorBoundary>
366
- </AnimationProvider>
367
- </motion.div>
368
- </AnimatePresence>
304
+ <SlideRenderer
305
+ slides={slides}
306
+ currentSlide={currentSlide}
307
+ animationStep={animationStep}
308
+ totalSteps={totalSteps}
309
+ direction={direction}
310
+ showAllAnimations={showAllAnimations}
311
+ transition={transition}
312
+ directionalTransition={directionalTransition}
313
+ onTransitionComplete={onTransitionComplete}
314
+ />
369
315
  </div>
370
316
  )}
371
317
  </LayoutGroup>
@@ -427,9 +373,15 @@ export function SlideDeck({ slides, transition, directionalTransition }: SlideDe
427
373
  className="h-full w-full origin-top-left scale-[0.25]"
428
374
  style={{ width: "400%", height: "400%" }}
429
375
  >
430
- <SlideErrorBoundary slideIndex={index} slideTitle={slideConfig.title}>
431
- <SlideComponent slideNumber={index + 1} totalSlides={slides.length} />
432
- </SlideErrorBoundary>
376
+ <AnimationProvider
377
+ currentStep={slideConfig.steps}
378
+ totalSteps={slideConfig.steps}
379
+ showAllAnimations={true}
380
+ >
381
+ <SlideErrorBoundary slideIndex={index} slideTitle={slideConfig.title}>
382
+ <SlideComponent slideNumber={index + 1} totalSlides={slides.length} />
383
+ </SlideErrorBoundary>
384
+ </AnimationProvider>
433
385
  </div>
434
386
  <div className="absolute inset-0 bg-black/0 transition-colors group-hover:bg-black/20" />
435
387
  <div className="absolute bottom-2 left-2 rounded bg-black/70 px-2 py-1 text-xs font-medium text-white">