promptslide 0.3.17 → 0.3.19
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/CHANGELOG.md +14 -0
- package/README.md +76 -0
- package/dist/index.d.ts +29 -4
- package/dist/index.js +1427 -359
- package/dist/index.js.map +1 -1
- package/package.json +31 -31
- package/src/commands/build.mjs +4 -1
- package/src/commands/clone.mjs +5 -2
- package/src/commands/create.mjs +45 -14
- package/src/commands/pull.mjs +6 -3
- package/src/commands/studio.mjs +4 -3
- package/src/core/annotations/annotation-panel.tsx +18 -12
- package/src/core/index.ts +11 -5
- package/src/core/inspector.tsx +155 -0
- package/src/core/loop/config.d.mts +13 -0
- package/src/core/loop/config.mjs +65 -0
- package/src/core/loop/context.tsx +20 -0
- package/src/core/loop/loop-settings.tsx +292 -0
- package/src/core/loop/use-loop-playback.ts +115 -0
- package/src/core/slide-deck.tsx +459 -125
- package/src/core/slide-renderer.tsx +5 -4
- package/src/core/toolbar-action.tsx +38 -0
- package/src/core/types.ts +14 -0
- package/src/core/use-slide-navigation.ts +27 -0
- package/src/core/view-menu.tsx +130 -0
- package/src/editor/README.md +45 -0
- package/src/editor/geometry.ts +76 -0
- package/src/editor/mount.ts +24 -0
- package/src/editor/plugin.mjs +189 -0
- package/src/editor/source.mjs +363 -0
- package/src/editor/studio.css +978 -0
- package/src/editor/studio.tsx +1964 -0
- package/src/utils/deck-config.mjs +6 -0
- package/src/utils/loop-config.mjs +70 -0
- package/src/vite/config.mjs +23 -2
- package/src/vite/plugin.mjs +21 -4
- package/templates/default/src/deck-config.ts +2 -2
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/slide-renderer.tsx","../src/core/slide-error-boundary.tsx","../src/core/slide-embed.tsx","../src/core/slide-deck.tsx","../src/core/annotations/annotation-overlay.tsx","../src/core/annotations/annotation-form.tsx","../src/core/annotations/annotation-pin.tsx","../src/core/annotations/selectors.ts","../src/core/annotations/annotation-panel.tsx","../src/core/annotations/use-annotations.ts","../src/core/annotations/adapters/http.ts","../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 (0 = visible from slide entry) */\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={isVisible ? false : \"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={isVisible ? false : \"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 // Render the next slide fully beneath the current one, then fade the\n // outgoing slide away. This keeps the frame opaque throughout the change.\n enter: { opacity: 1, zIndex: 0 },\n center: { opacity: 1, zIndex: 0 },\n exit: { opacity: 0, zIndex: 1 }\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, useRef, 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\nconst POSITION_KEY = \"promptslide:position\"\n\nfunction slideKey(slides: SlideConfig[], index: number): string {\n return slides[index]?.id || String(index + 1)\n}\n\nfunction slideFromHash(slides: SlideConfig[]): number | null {\n if (typeof window === \"undefined\" || !window.location.hash) return null\n let hash: string\n try {\n hash = decodeURIComponent(window.location.hash.slice(1))\n } catch {\n return null\n }\n const byId = slides.findIndex(slide => slide.id === hash)\n if (byId >= 0) return byId\n if (/^[1-9]\\d*$/.test(hash)) {\n const index = Number(hash) - 1\n if (index < slides.length) return index\n }\n return null\n}\n\nfunction savedStep(slides: SlideConfig[], index: number): number {\n if (typeof window === \"undefined\") return 0\n try {\n const saved = JSON.parse(window.sessionStorage.getItem(POSITION_KEY) || \"null\")\n if (saved?.slide === slideKey(slides, index) && Number.isInteger(saved.step)) {\n return Math.max(0, Math.min(saved.step, slides[index]?.steps ?? 0))\n }\n } catch {\n /* Storage may be unavailable. */\n }\n return 0\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(() => slideFromHash(slides) ?? initialSlide)\n const [animationStep, setAnimationStep] = useState(() =>\n savedStep(slides, slideFromHash(slides) ?? initialSlide)\n )\n const slidesRef = useRef(slides)\n const activeKeyRef = useRef(slideKey(slides, slideFromHash(slides) ?? initialSlide))\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 useEffect(() => {\n if (typeof window === \"undefined\" || slides.length === 0) return\n if (slidesRef.current !== slides) {\n slidesRef.current = slides\n const previousKey = activeKeyRef.current\n const movedIndex = slides.findIndex(slide => slide.id && slide.id === previousKey)\n if (movedIndex >= 0 && movedIndex !== currentSlide) {\n setCurrentSlide(movedIndex)\n return\n }\n if (movedIndex < 0 && !/^[1-9]\\d*$/.test(previousKey) && currentSlide !== 0) {\n setAnimationStep(0)\n setCurrentSlide(0)\n return\n }\n }\n if (!slides[currentSlide]) {\n setCurrentSlide(0)\n setAnimationStep(0)\n return\n }\n const key = slideKey(slides, currentSlide)\n activeKeyRef.current = key\n const hash = `#${encodeURIComponent(key)}`\n if (window.location.hash !== hash) {\n window.history.replaceState(window.history.state, \"\", hash)\n }\n try {\n window.sessionStorage.setItem(\n POSITION_KEY,\n JSON.stringify({ slide: key, step: animationStep })\n )\n } catch {\n /* Storage may be unavailable. */\n }\n }, [slides, currentSlide, animationStep])\n\n useEffect(() => {\n const handleHashChange = () => {\n const index = slideFromHash(slides) ?? 0\n if (index === currentSlide) return\n setNavState({ status: \"transitioning\", direction: index > currentSlide ? 1 : -1 })\n setAnimationStep(0)\n setCurrentSlide(index)\n onSlideChange?.(index)\n }\n window.addEventListener(\"hashchange\", handleHashChange)\n return () => window.removeEventListener(\"hashchange\", handleHashChange)\n }, [slides, currentSlide, onSlideChange])\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 { 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 fit viewport while preserving aspect ratio\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=\"h-screen w-screen overflow-hidden bg-black\">\n <div\n className=\"absolute left-1/2 top-1/2 overflow-hidden\"\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n transform: `translate(-50%, -50%) 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 {\n ChevronLeft,\n ChevronRight,\n Download,\n Grid3X3,\n List,\n MessageCircle,\n Monitor,\n PanelLeftClose,\n PanelLeftOpen,\n Play\n} from \"lucide-react\"\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\"\n\nimport type { Annotation, AnnotationTarget } from \"./annotations\"\nimport type { SlideTransitionType } from \"./transitions\"\nimport type { SlideConfig } from \"./types\"\n\nimport { SLIDE_DIMENSIONS } from \"./animation-config\"\nimport { AnimationProvider } from \"./animation-context\"\nimport { AnnotationOverlay, AnnotationPanel, useAnnotations } from \"./annotations\"\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\"\nconst NARROW_VIEWPORT_WIDTH = 768\nconst DEFAULT_THUMBNAIL_WIDTH = 240\nconst MIN_THUMBNAIL_WIDTH = 176\nconst MAX_THUMBNAIL_WIDTH = 480\nconst THUMBNAIL_WIDTH_STORAGE_KEY = \"promptslide:thumbnail-width\"\n\nfunction GridThumbnail({\n slide,\n index,\n total\n}: {\n slide: SlideConfig\n index: number\n total: number\n}) {\n const viewportRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLDivElement>(null)\n const SlideComponent = slide.component\n\n useLayoutEffect(() => {\n const viewport = viewportRef.current\n const canvas = canvasRef.current\n if (!viewport || !canvas) return\n const resize = () => {\n canvas.style.transform = `scale(${viewport.clientWidth / SLIDE_DIMENSIONS.width})`\n }\n resize()\n const observer = new ResizeObserver(resize)\n observer.observe(viewport)\n return () => observer.disconnect()\n }, [])\n\n return (\n <div ref={viewportRef} className=\"absolute inset-0 overflow-hidden\">\n <div\n ref={canvasRef}\n className=\"absolute top-0 left-0 origin-top-left\"\n style={{ width: SLIDE_DIMENSIONS.width, height: SLIDE_DIMENSIONS.height }}\n >\n <AnimationProvider currentStep={slide.steps} totalSteps={slide.steps} showAllAnimations>\n <SlideErrorBoundary slideIndex={index} slideTitle={slide.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={total} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n </div>\n )\n}\n\nfunction ListSlide({ slide, index, total }: { slide: SlideConfig; index: number; total: number }) {\n const viewportRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLDivElement>(null)\n const SlideComponent = slide.component\n\n useLayoutEffect(() => {\n const viewport = viewportRef.current\n const canvas = canvasRef.current\n if (!viewport || !canvas) return\n const resize = () => {\n canvas.style.transform = `scale(${viewport.clientWidth / SLIDE_DIMENSIONS.width})`\n }\n resize()\n const observer = new ResizeObserver(resize)\n observer.observe(viewport)\n return () => observer.disconnect()\n }, [])\n\n return (\n <div\n ref={viewportRef}\n className=\"relative aspect-video w-full overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-sm print:m-0 print:h-[1080px] print:w-[1920px] print:break-after-page print:rounded-none print:border-0 print:shadow-none\"\n >\n <div\n ref={canvasRef}\n className=\"list-slide-canvas absolute top-0 left-0 origin-top-left\"\n style={{ width: SLIDE_DIMENSIONS.width, height: SLIDE_DIMENSIONS.height }}\n >\n <AnimationProvider currentStep={slide.steps} totalSteps={slide.steps} showAllAnimations>\n <SlideErrorBoundary slideIndex={index} slideTitle={slide.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={total} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n </div>\n )\n}\n\ninterface SlideDeckProps {\n slides: SlideConfig[]\n transition?: SlideTransitionType\n directionalTransition?: boolean\n /** Annotation data to display. When provided (even empty array), annotation UI is enabled. When undefined, annotation UI is hidden. */\n annotations?: Annotation[]\n /** Called when the user creates an annotation */\n onAnnotationAdd?: (\n slideIndex: number,\n slideTitle: string,\n target: AnnotationTarget,\n body: string,\n slideId?: string\n ) => void\n /** Called when the user deletes an annotation */\n onAnnotationDelete?: (id: string) => void\n onAnnotationUpdate?: (id: string, patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => void\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 let cancelled = false\n const markReady = async () => {\n await document.fonts.ready\n await Promise.all(Array.from(document.images, image => image.decode().catch(() => {})))\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n if (!cancelled) setReady(true)\n })\n )\n }\n void markReady()\n return () => {\n cancelled = true\n }\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({\n slides,\n transition,\n directionalTransition,\n annotations,\n onAnnotationAdd,\n onAnnotationDelete,\n onAnnotationUpdate\n}: 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 // Use internal useAnnotations as fallback when no external annotations prop is provided\n const internal = useAnnotations(slides)\n const isExternallyManaged = annotations !== undefined\n const effectiveAnnotations = isExternallyManaged ? annotations : internal.annotations\n const effectiveAdd = isExternallyManaged ? onAnnotationAdd : internal.addAnnotation\n const effectiveDelete = isExternallyManaged ? onAnnotationDelete : internal.deleteAnnotation\n const effectiveUpdate = isExternallyManaged ? onAnnotationUpdate : internal.updateAnnotation\n\n const openCount = useMemo(\n () => effectiveAnnotations.filter(a => a.status === \"open\").length,\n [effectiveAnnotations]\n )\n const getSlideAnnotations = useCallback(\n (slideIndex: number) =>\n effectiveAnnotations.filter(a =>\n a.slideId ? a.slideId === slides[slideIndex]?.id : a.slideIndex === slideIndex\n ),\n [effectiveAnnotations, slides]\n )\n const unlinkedAnnotations = useMemo(\n () =>\n effectiveAnnotations.filter(a => a.slideId && !slides.some(slide => slide.id === a.slideId)),\n [effectiveAnnotations, slides]\n )\n\n const [viewMode, setViewMode] = useState<ViewMode>(\"slide\")\n const [isPresentationMode, setIsPresentationMode] = useState(false)\n const [viewportWidth, setViewportWidth] = useState(() =>\n typeof window === \"undefined\" ? 1280 : window.innerWidth\n )\n const [showThumbnailRail, setShowThumbnailRail] = useState(() =>\n typeof window === \"undefined\" ? true : window.innerWidth >= NARROW_VIEWPORT_WIDTH\n )\n const [thumbnailWidth, setThumbnailWidth] = useState(() => {\n if (typeof window === \"undefined\") return DEFAULT_THUMBNAIL_WIDTH\n const savedWidth = Number(window.localStorage.getItem(THUMBNAIL_WIDTH_STORAGE_KEY))\n return Number.isFinite(savedWidth) && savedWidth >= MIN_THUMBNAIL_WIDTH\n ? Math.min(savedWidth, MAX_THUMBNAIL_WIDTH)\n : DEFAULT_THUMBNAIL_WIDTH\n })\n const [isAnnotationMode, setIsAnnotationMode] = useState(false)\n const [showAnnotationPanel, setShowAnnotationPanel] = useState(false)\n const [selectedAnnotationId, setSelectedAnnotationId] = useState<string | null>(null)\n const [hoveredAnnotationId, setHoveredAnnotationId] = useState<string | null>(null)\n const [isResizingThumbnails, setIsResizingThumbnails] = useState(false)\n const [isDragCollapsed, setIsDragCollapsed] = useState(false)\n const [isAnimatingDragBoundary, setIsAnimatingDragBoundary] = useState(false)\n const [scale, setScale] = useState(1)\n const containerRef = useRef<HTMLDivElement>(null)\n const slideContainerRef = useRef<HTMLDivElement>(null)\n const previewViewportRef = useRef<HTMLDivElement>(null)\n const activeThumbnailRef = useRef<HTMLButtonElement>(null)\n const preferredRailOpenRef = useRef(true)\n const wasNarrowViewportRef = useRef(viewportWidth < NARROW_VIEWPORT_WIDTH)\n const resizeStartRef = useRef<{\n pointerId: number\n pointerX: number\n width: number\n } | null>(null)\n const previousUserSelectRef = useRef(\"\")\n const previousCursorRef = useRef(\"\")\n const dragCollapsedRef = useRef(false)\n const dragAnimationTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const isNarrowViewport = viewportWidth < NARROW_VIEWPORT_WIDTH\n const maxThumbnailWidth = isNarrowViewport\n ? Math.max(120, Math.floor(viewportWidth * 0.8))\n : Math.min(MAX_THUMBNAIL_WIDTH, viewportWidth - 360)\n const minThumbnailWidth = Math.min(MIN_THUMBNAIL_WIDTH, maxThumbnailWidth)\n const visibleThumbnailWidth = Math.min(thumbnailWidth, maxThumbnailWidth)\n const isThumbnailRailVisible = showThumbnailRail && !isDragCollapsed\n\n const setThumbnailRailOpen = useCallback((open: boolean) => {\n preferredRailOpenRef.current = open\n setShowThumbnailRail(open)\n }, [])\n\n useEffect(() => {\n const handleResize = () => setViewportWidth(window.innerWidth)\n window.addEventListener(\"resize\", handleResize)\n return () => window.removeEventListener(\"resize\", handleResize)\n }, [])\n\n useEffect(() => {\n if (isNarrowViewport !== wasNarrowViewportRef.current) {\n setShowThumbnailRail(isNarrowViewport ? false : preferredRailOpenRef.current)\n if (isNarrowViewport) {\n setIsAnnotationMode(false)\n setShowAnnotationPanel(false)\n setSelectedAnnotationId(null)\n }\n wasNarrowViewportRef.current = isNarrowViewport\n }\n }, [isNarrowViewport])\n\n useEffect(() => {\n window.localStorage.setItem(THUMBNAIL_WIDTH_STORAGE_KEY, String(thumbnailWidth))\n }, [thumbnailWidth])\n\n useEffect(\n () => () => {\n if (resizeStartRef.current) {\n document.body.style.userSelect = previousUserSelectRef.current\n document.body.style.cursor = previousCursorRef.current\n }\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n },\n []\n )\n\n useEffect(() => {\n if (\n (!showThumbnailRail || isPresentationMode || viewMode !== \"slide\") &&\n resizeStartRef.current\n ) {\n resizeStartRef.current = null\n dragCollapsedRef.current = false\n setIsResizingThumbnails(false)\n setIsDragCollapsed(false)\n setIsAnimatingDragBoundary(false)\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n document.body.style.userSelect = previousUserSelectRef.current\n document.body.style.cursor = previousCursorRef.current\n }\n }, [showThumbnailRail, isPresentationMode, viewMode])\n\n useEffect(() => {\n if (!isResizingThumbnails) return\n\n const getDraggedWidth = (clientX: number) => {\n const start = resizeStartRef.current\n return start ? start.width + clientX - start.pointerX : null\n }\n const handlePointerMove = (event: PointerEvent) => {\n if (event.pointerId !== resizeStartRef.current?.pointerId) return\n const nextWidth = getDraggedWidth(event.clientX)\n if (nextWidth === null) return\n const collapsed = nextWidth < minThumbnailWidth\n if (collapsed !== dragCollapsedRef.current) {\n dragCollapsedRef.current = collapsed\n setIsDragCollapsed(collapsed)\n setIsAnimatingDragBoundary(true)\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n dragAnimationTimerRef.current = setTimeout(() => {\n setIsAnimatingDragBoundary(false)\n dragAnimationTimerRef.current = null\n }, 200)\n }\n if (!collapsed) setThumbnailWidth(Math.min(maxThumbnailWidth, nextWidth))\n }\n const stopResize = (event?: PointerEvent) => {\n if (event && event.pointerId !== resizeStartRef.current?.pointerId) return\n const nextWidth = event ? getDraggedWidth(event.clientX) : null\n const collapsed =\n event?.type === \"pointerup\" && nextWidth !== null && nextWidth < minThumbnailWidth\n resizeStartRef.current = null\n dragCollapsedRef.current = false\n document.body.style.userSelect = previousUserSelectRef.current\n document.body.style.cursor = previousCursorRef.current\n setIsResizingThumbnails(false)\n setIsDragCollapsed(false)\n if (collapsed) setThumbnailRailOpen(false)\n else if (nextWidth !== null) {\n setThumbnailWidth(Math.max(minThumbnailWidth, Math.min(maxThumbnailWidth, nextWidth)))\n }\n }\n const handleBlur = () => stopResize()\n\n window.addEventListener(\"pointermove\", handlePointerMove)\n window.addEventListener(\"pointerup\", stopResize)\n window.addEventListener(\"pointercancel\", stopResize)\n window.addEventListener(\"blur\", handleBlur)\n return () => {\n window.removeEventListener(\"pointermove\", handlePointerMove)\n window.removeEventListener(\"pointerup\", stopResize)\n window.removeEventListener(\"pointercancel\", stopResize)\n window.removeEventListener(\"blur\", handleBlur)\n }\n }, [isResizingThumbnails, minThumbnailWidth, maxThumbnailWidth, setThumbnailRailOpen])\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 useEffect(() => {\n if (viewMode === \"slide\" && !isPresentationMode && showThumbnailRail) {\n activeThumbnailRef.current?.scrollIntoView({ block: \"nearest\" })\n }\n }, [currentSlide, isPresentationMode, showThumbnailRail, viewMode])\n\n // Calculate scale factor for presentation mode\n useEffect(() => {\n const calculateScale = () => {\n if (!isPresentationMode) {\n setScale(1)\n return\n }\n const availableWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n const scaleX = availableWidth / 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 // Keep slide layout at its design size; only scale the rendered canvas.\n useLayoutEffect(() => {\n const viewport = previewViewportRef.current\n const canvas = slideContainerRef.current\n if (!viewport || !canvas) return\n const resize = (width: number, height: number) => {\n const fitScale = Math.min(width / SLIDE_DIMENSIONS.width, height / SLIDE_DIMENSIONS.height)\n canvas.style.transform = `scale(${fitScale})`\n }\n resize(viewport.clientWidth, viewport.clientHeight)\n const observer = new ResizeObserver(([entry]) => {\n if (!entry) return\n resize(entry.contentRect.width, entry.contentRect.height)\n })\n observer.observe(viewport)\n return () => observer.disconnect()\n }, [viewMode, isPresentationMode])\n\n const toggleCommentMode = useCallback(() => {\n const next = !isAnnotationMode\n setIsAnnotationMode(next)\n setShowAnnotationPanel(next)\n if (!next) {\n setSelectedAnnotationId(null)\n setHoveredAnnotationId(null)\n }\n }, [isAnnotationMode])\n\n const handleExportPdf = useCallback(async () => {\n try {\n const response = await fetch(\"/__promptslide_pdf\")\n if (response.ok && response.headers.get(\"content-type\")?.includes(\"application/pdf\")) {\n const blob = await response.blob()\n const url = URL.createObjectURL(blob)\n const link = document.createElement(\"a\")\n link.href = url\n link.download = \"slides.pdf\"\n link.click()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n return\n }\n } catch {\n /* Static builds use the browser print fallback. */\n }\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 }, [viewMode])\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null\n if (target?.closest(\"input, textarea, [contenteditable='true']\")) return\n if (e.altKey || e.ctrlKey || e.metaKey) return\n const key = e.key.toLowerCase()\n if (e.repeat && \"fvglcdt\".includes(key)) return\n\n if (key === \"f\") {\n e.preventDefault()\n void togglePresentationMode()\n return\n }\n\n if (key === \"v\" && !isPresentationMode) {\n e.preventDefault()\n setViewMode(\"slide\")\n return\n }\n\n if (key === \"g\") {\n e.preventDefault()\n setViewMode(prev => (prev === \"grid\" ? \"slide\" : \"grid\"))\n return\n }\n\n if (key === \"l\") {\n e.preventDefault()\n setViewMode(prev => (prev === \"list\" ? \"slide\" : \"list\"))\n return\n }\n\n if (key === \"c\" && !isPresentationMode) {\n e.preventDefault()\n toggleCommentMode()\n return\n }\n\n if (key === \"d\" && !isPresentationMode) {\n e.preventDefault()\n void handleExportPdf()\n return\n }\n\n if (viewMode === \"slide\" && !isPresentationMode && key === \"t\") {\n e.preventDefault()\n setThumbnailRailOpen(!showThumbnailRail)\n return\n }\n\n if (viewMode !== \"slide\" || (isAnnotationMode && !isPresentationMode)) 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 }, [\n advance,\n goBack,\n viewMode,\n togglePresentationMode,\n isAnnotationMode,\n isPresentationMode,\n setThumbnailRailOpen,\n showThumbnailRail,\n toggleCommentMode,\n handleExportPdf\n ])\n\n return (\n <div className=\"min-h-screen w-full bg-neutral-950 text-foreground\">\n <style>{`\n @media print {\n .list-slide-canvas {\n transform: scale(1.5) !important;\n }\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 z-50 flex gap-1 rounded-lg border border-neutral-800 bg-neutral-950/90 p-1 backdrop-blur-sm transition-[right] duration-200 ease-out print:hidden\",\n (isPresentationMode || (isNarrowViewport && isAnnotationMode && showAnnotationPanel)) &&\n \"hidden\",\n isAnnotationMode && showAnnotationPanel ? \"right-[21rem]\" : \"right-4\"\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 (V)\"\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 (L)\"\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 (G)\"\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={toggleCommentMode}\n className={cn(\n \"relative inline-flex h-8 items-center justify-center rounded-md transition-colors\",\n isAnnotationMode\n ? \"border border-[#FF6B35]/50 bg-[#FF6B35]/15 p-[7px] text-[#FF6B35] hover:border-[#FF6B35] hover:bg-[#FF6B35]/25\"\n : \"p-2 text-neutral-400 hover:bg-neutral-800 hover:text-white\"\n )}\n title=\"Comment (C)\"\n >\n <MessageCircle className=\"h-4 w-4\" />\n {openCount > 0 && (\n <span className=\"absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-[#FF6B35] text-[10px] font-bold text-white\">\n {openCount}\n </span>\n )}\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 (D)\"\n >\n <Download className=\"h-4 w-4\" />\n </button>\n <button\n onClick={togglePresentationMode}\n className=\"inline-flex h-8 items-center justify-center gap-1.5 rounded-md border border-[#FF6B35]/50 bg-[#FF6B35]/15 px-3 text-sm font-semibold text-[#FF6B35] transition-colors hover:border-[#FF6B35] hover:bg-[#FF6B35]/25\"\n title=\"Present (F)\"\n >\n <Play className=\"h-3.5 w-3.5 fill-current\" />\n <span>Present</span>\n </button>\n </div>\n\n {/* Slide View */}\n {viewMode === \"slide\" && (\n <div\n className={cn(\"flex h-screen w-full print:hidden\", isPresentationMode ? \"bg-black\" : \"\")}\n >\n {!isPresentationMode && (\n <>\n <div\n className={cn(\n \"relative z-10 h-screen shrink-0\",\n isNarrowViewport && \"fixed inset-y-0 left-0\",\n isResizingThumbnails && !isAnimatingDragBoundary\n ? \"transition-none\"\n : \"transition-[width] duration-200 ease-out motion-reduce:transition-none\"\n )}\n style={{ width: isThumbnailRailVisible ? visibleThumbnailWidth : 0 }}\n >\n <div className=\"h-full w-full overflow-hidden\">\n <aside\n id=\"presentation-thumbnails\"\n aria-label=\"Slide thumbnails\"\n aria-hidden={!isThumbnailRailVisible}\n inert={!isThumbnailRailVisible}\n className={cn(\n \"flex h-screen shrink-0 flex-col border-r border-neutral-800 bg-neutral-950 text-white transition-opacity motion-reduce:transition-none\",\n isThumbnailRailVisible\n ? \"opacity-100 delay-100 duration-100\"\n : \"opacity-0 duration-75\"\n )}\n style={{ width: visibleThumbnailWidth }}\n >\n <div className=\"flex items-center justify-between border-b border-neutral-800 px-3 py-2\">\n <span className=\"text-sm font-semibold\">Slides ({slides.length})</span>\n <button\n type=\"button\"\n onClick={() => setThumbnailRailOpen(false)}\n className=\"rounded p-2 text-neutral-400 hover:bg-neutral-800 hover:text-white\"\n aria-label=\"Hide slide thumbnails\"\n title=\"Hide thumbnails (T)\"\n >\n <PanelLeftClose className=\"h-4 w-4\" />\n </button>\n </div>\n <div className=\"min-h-0 flex-1 space-y-3 overflow-y-auto p-3\">\n {slides.map((slideConfig, index) => (\n <button\n key={slideConfig.id ?? index}\n ref={index === currentSlide ? activeThumbnailRef : undefined}\n type=\"button\"\n onClick={() => goToSlide(index)}\n aria-label={`Go to slide ${index + 1}${slideConfig.title ? `: ${slideConfig.title}` : \"\"}`}\n aria-current={index === currentSlide ? \"page\" : undefined}\n className={cn(\n \"block w-full rounded-lg border p-1.5 text-left transition-colors focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#FF6B35]\",\n index === currentSlide\n ? \"border-[#FF6B35] bg-[#FF6B35]/15 ring-1 ring-[#FF6B35]\"\n : \"border-transparent hover:border-neutral-600 hover:bg-neutral-800\"\n )}\n >\n <div className=\"relative aspect-video w-full overflow-hidden rounded bg-black\">\n <GridThumbnail\n slide={slideConfig}\n index={index}\n total={slides.length}\n />\n </div>\n <div className=\"mt-1.5 flex items-baseline gap-2 px-0.5 text-xs\">\n {slideConfig.title ? (\n <>\n <span className=\"font-mono text-neutral-400\">{index + 1}</span>\n <span className=\"truncate\">{slideConfig.title}</span>\n </>\n ) : (\n <span>Slide {index + 1}</span>\n )}\n </div>\n </button>\n ))}\n </div>\n </aside>\n </div>\n {isThumbnailRailVisible && (\n <div\n role=\"separator\"\n aria-label=\"Resize slide thumbnails\"\n aria-orientation=\"vertical\"\n aria-valuemin={minThumbnailWidth}\n aria-valuemax={maxThumbnailWidth}\n aria-valuenow={visibleThumbnailWidth}\n tabIndex={0}\n className={cn(\n \"absolute inset-y-0 -right-1 w-2 cursor-col-resize touch-none focus-visible:outline-none after:pointer-events-none after:absolute after:inset-y-0 after:right-1 after:w-0.5 after:bg-transparent after:content-[''] after:transition-colors hover:after:bg-[#FF6B35]/50 focus-visible:after:bg-[#FF6B35]/50\",\n isResizingThumbnails && \"after:bg-[#FF6B35]/60\"\n )}\n onPointerDown={event => {\n if (event.button !== 0) return\n event.preventDefault()\n resizeStartRef.current = {\n pointerId: event.pointerId,\n pointerX: event.clientX,\n width: visibleThumbnailWidth\n }\n dragCollapsedRef.current = false\n setIsAnimatingDragBoundary(false)\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n setIsResizingThumbnails(true)\n previousUserSelectRef.current = document.body.style.userSelect\n previousCursorRef.current = document.body.style.cursor\n document.body.style.userSelect = \"none\"\n document.body.style.cursor = \"col-resize\"\n }}\n onKeyDown={event => {\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") {\n event.preventDefault()\n event.stopPropagation()\n const amount = event.key === \"ArrowRight\" ? 16 : -16\n setThumbnailWidth(\n Math.max(\n minThumbnailWidth,\n Math.min(maxThumbnailWidth, visibleThumbnailWidth + amount)\n )\n )\n }\n }}\n />\n )}\n </div>\n <div\n aria-hidden={isThumbnailRailVisible || isResizingThumbnails}\n inert={isThumbnailRailVisible || isResizingThumbnails}\n className={cn(\n \"fixed top-4 left-4 z-50 rounded-lg border border-neutral-800 bg-neutral-950/90 backdrop-blur-sm transition-opacity duration-150 motion-reduce:transition-none\",\n isThumbnailRailVisible || isResizingThumbnails\n ? \"pointer-events-none opacity-0\"\n : \"opacity-100 delay-200\"\n )}\n >\n <button\n type=\"button\"\n onClick={() => setThumbnailRailOpen(true)}\n className=\"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\"\n aria-label=\"Show slide thumbnails\"\n title=\"Show thumbnails (T)\"\n >\n <PanelLeftOpen className=\"h-4 w-4\" />\n </button>\n </div>\n </>\n )}\n <div\n ref={containerRef}\n role=\"presentation\"\n tabIndex={isPresentationMode ? 0 : undefined}\n className={cn(\n \"flex min-w-0 flex-1 flex-col items-center justify-center overflow-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\n ref={previewViewportRef}\n className=\"relative aspect-video w-full max-w-7xl overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-2xl\"\n >\n <div\n ref={slideContainerRef}\n className=\"absolute top-0 left-0 overflow-hidden\"\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n transformOrigin: \"top left\"\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 {isAnnotationMode && (\n <AnnotationOverlay\n slides={slides}\n currentSlide={currentSlide}\n slideContainerRef={slideContainerRef}\n selectedId={selectedAnnotationId}\n hoveredId={hoveredAnnotationId}\n onSelectId={setSelectedAnnotationId}\n onShowPanel={() => setShowAnnotationPanel(true)}\n slideAnnotations={getSlideAnnotations(currentSlide)}\n addAnnotation={effectiveAdd ?? (() => {})}\n />\n )}\n </div>\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 title=\"Previous step or slide (←)\"\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 </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 title=\"Next step or slide (→ / Space)\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </div>\n )}\n </div>\n\n {/* Annotation Panel — beside the slide */}\n {!isPresentationMode && (\n <div\n aria-hidden={!isAnnotationMode || !showAnnotationPanel}\n inert={!isAnnotationMode || !showAnnotationPanel}\n className={cn(\n \"h-full shrink-0 overflow-hidden transition-[width,transform] duration-200 ease-out motion-reduce:transition-none\",\n isNarrowViewport && \"fixed inset-y-0 right-0 z-50 shadow-xl\",\n isNarrowViewport &&\n (!isAnnotationMode || !showAnnotationPanel) &&\n \"translate-x-full\"\n )}\n style={{\n width:\n isAnnotationMode && showAnnotationPanel\n ? isNarrowViewport\n ? \"min(20rem, 90vw)\"\n : \"20rem\"\n : 0\n }}\n >\n <div\n className={cn(\n \"h-full transition-opacity motion-reduce:transition-none\",\n isAnnotationMode && showAnnotationPanel\n ? \"opacity-100 delay-100 duration-100\"\n : \"opacity-0 duration-75\"\n )}\n >\n <AnnotationPanel\n annotations={getSlideAnnotations(currentSlide)}\n unlinkedAnnotations={unlinkedAnnotations}\n selectedId={selectedAnnotationId}\n onSelect={setSelectedAnnotationId}\n onHover={setHoveredAnnotationId}\n onDelete={effectiveDelete ?? (() => {})}\n onUpdate={effectiveUpdate ?? (() => {})}\n onClose={() => {\n setIsAnnotationMode(false)\n setShowAnnotationPanel(false)\n setSelectedAnnotationId(null)\n setHoveredAnnotationId(null)\n }}\n />\n </div>\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 prevSection = index > 0 ? slides[index - 1]?.section : undefined\n const showSectionHeader = slideConfig.section && slideConfig.section !== prevSection\n\n return (\n <div key={slideConfig.id ?? index} className=\"contents\">\n {showSectionHeader && (\n <h3 className=\"col-span-full mt-4 mb-0 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-[#FF6B35] hover:shadow-lg hover:shadow-[#FF6B35]/10\"\n >\n <GridThumbnail slide={slideConfig} index={index} total={slides.length} />\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 <ListSlide\n key={slideConfig.id ?? index}\n slide={slideConfig}\n index={index}\n total={slides.length}\n />\n ))}\n </div>\n </div>\n </div>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nimport type { SlideConfig } from \"../types\"\nimport type { Annotation, AnnotationTarget } from \"./types\"\n\nimport { AnnotationForm } from \"./annotation-form\"\nimport { AnnotationPin } from \"./annotation-pin\"\nimport { buildElementTarget, resolveTarget } from \"./selectors\"\n\ninterface AnnotationOverlayProps {\n slides: SlideConfig[]\n currentSlide: number\n /** Ref to the slide container element (the div wrapping SlideRenderer) */\n slideContainerRef: React.RefObject<HTMLDivElement | null>\n selectedId: string | null\n hoveredId: string | null\n onSelectId: (id: string | null) => void\n onShowPanel: () => void\n slideAnnotations: Annotation[]\n addAnnotation: (\n slideIndex: number,\n slideTitle: string,\n target: AnnotationTarget,\n body: string,\n slideId?: string\n ) => void\n}\n\ninterface PendingAnnotation {\n target: AnnotationTarget\n xPercent: number\n yPercent: number\n}\n\nexport function AnnotationOverlay({\n slides,\n currentSlide,\n slideContainerRef,\n selectedId,\n hoveredId,\n onSelectId,\n onShowPanel,\n slideAnnotations,\n addAnnotation\n}: AnnotationOverlayProps) {\n const [pending, setPending] = useState<PendingAnnotation | null>(null)\n const [hoveredElement, setHoveredElement] = useState<DOMRect | null>(null)\n const overlayRef = useRef<HTMLDivElement>(null)\n\n const slideTitle = slides[currentSlide]?.title || `Slide ${currentSlide + 1}`\n\n // Resolve annotation positions — use the element if found, otherwise fallback coordinates\n const resolvedAnnotations = slideAnnotations.map((a, i) => {\n const container = slideContainerRef.current\n if (!container) {\n return {\n annotation: a,\n xPercent: a.target.position.xPercent,\n yPercent: a.target.position.yPercent,\n number: i + 1\n }\n }\n\n const { element } = resolveTarget(a.target, container)\n if (element) {\n const rect = element.getBoundingClientRect()\n const containerRect = container.getBoundingClientRect()\n const xPercent =\n ((rect.left + rect.width / 2 - containerRect.left) / containerRect.width) * 100\n const yPercent =\n ((rect.top + rect.height / 2 - containerRect.top) / containerRect.height) * 100\n return { annotation: a, xPercent, yPercent, number: i + 1 }\n }\n\n return {\n annotation: a,\n xPercent: a.target.position.xPercent,\n yPercent: a.target.position.yPercent,\n number: i + 1\n }\n })\n\n const handleOverlayClick = useCallback(\n (e: React.MouseEvent) => {\n const container = slideContainerRef.current\n if (!container) return\n\n // Get the element under the click by temporarily hiding the overlay\n const overlay = overlayRef.current\n if (overlay) overlay.style.pointerEvents = \"none\"\n const elementUnder = document.elementFromPoint(e.clientX, e.clientY) as HTMLElement | null\n if (overlay) overlay.style.pointerEvents = \"\"\n\n if (!elementUnder || !container.contains(elementUnder)) {\n setPending(null)\n onSelectId(null)\n return\n }\n\n // Pick the most specific meaningful element (skip tiny text nodes, pick their parent)\n let target = elementUnder\n if (\n target.tagName === \"SPAN\" &&\n target.parentElement &&\n container.contains(target.parentElement)\n ) {\n // For inline spans, prefer their parent for a more meaningful target\n const parent = target.parentElement\n if (parent.tagName !== \"DIV\" || parent.children.length <= 3) {\n target = parent\n }\n }\n\n const annotationTarget = buildElementTarget(target, container)\n const containerRect = container.getBoundingClientRect()\n const xPercent = ((e.clientX - containerRect.left) / containerRect.width) * 100\n const yPercent = ((e.clientY - containerRect.top) / containerRect.height) * 100\n\n setPending({ target: annotationTarget, xPercent, yPercent })\n onSelectId(null)\n },\n [slideContainerRef, onSelectId]\n )\n\n const handleSubmit = useCallback(\n (text: string) => {\n if (!pending) return\n addAnnotation(currentSlide, slideTitle, pending.target, text, slides[currentSlide]?.id)\n setPending(null)\n onShowPanel()\n },\n [pending, currentSlide, slideTitle, slides, addAnnotation, onShowPanel]\n )\n\n // Track hover for element highlighting\n const handleMouseMove = useCallback(\n (e: React.MouseEvent) => {\n if (pending) {\n setHoveredElement(null)\n return\n }\n\n const container = slideContainerRef.current\n if (!container) return\n\n const overlay = overlayRef.current\n if (overlay) overlay.style.pointerEvents = \"none\"\n const elementUnder = document.elementFromPoint(e.clientX, e.clientY) as HTMLElement | null\n if (overlay) overlay.style.pointerEvents = \"\"\n\n if (elementUnder && container.contains(elementUnder) && elementUnder !== container) {\n const containerRect = container.getBoundingClientRect()\n const elRect = elementUnder.getBoundingClientRect()\n const scaleX = containerRect.width / container.offsetWidth\n const scaleY = containerRect.height / container.offsetHeight\n setHoveredElement(\n new DOMRect(\n (elRect.left - containerRect.left) / scaleX,\n (elRect.top - containerRect.top) / scaleY,\n elRect.width / scaleX,\n elRect.height / scaleY\n )\n )\n } else {\n setHoveredElement(null)\n }\n },\n [slideContainerRef, pending]\n )\n\n // Clear pending when slide changes\n useEffect(() => {\n setPending(null)\n onSelectId(null)\n setHoveredElement(null)\n }, [currentSlide, onSelectId])\n\n return (\n <>\n {/* Hover highlight */}\n {hoveredElement && (\n <div\n className=\"pointer-events-none absolute z-20 rounded-lg border-2 border-dashed border-[#FF6B35]/50 bg-[#FF6B35]/5\"\n style={{\n left: hoveredElement.x,\n top: hoveredElement.y,\n width: hoveredElement.width,\n height: hoveredElement.height\n }}\n />\n )}\n\n {/* Click capture overlay */}\n <div\n ref={overlayRef}\n role=\"button\"\n tabIndex={0}\n className=\"absolute inset-0 z-20\"\n style={{\n cursor: `url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none'%3E%3Ccircle cx='12' cy='12' r='8' stroke='%23FF6B35' stroke-width='2' opacity='0.8'/%3E%3Ccircle cx='12' cy='12' r='2' fill='%23FF6B35'/%3E%3C/svg%3E\") 12 12, crosshair`\n }}\n onClick={handleOverlayClick}\n onKeyDown={e => {\n if (e.key === \"Escape\") {\n setPending(null)\n onSelectId(null)\n }\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setHoveredElement(null)}\n />\n\n {/* Annotation pins */}\n {resolvedAnnotations\n .filter(({ annotation }) => annotation.status === \"open\" || annotation.id === hoveredId)\n .map(({ annotation, xPercent, yPercent, number }) => (\n <AnnotationPin\n key={annotation.id}\n number={number}\n status={annotation.status}\n xPercent={xPercent}\n yPercent={yPercent}\n isSelected={annotation.id === selectedId}\n onClick={() => {\n onSelectId(annotation.id === selectedId ? null : annotation.id)\n onShowPanel()\n setPending(null)\n }}\n />\n ))}\n\n {/* New annotation form */}\n {pending && (\n <AnnotationForm\n xPercent={pending.xPercent}\n yPercent={pending.yPercent}\n onSubmit={handleSubmit}\n onCancel={() => setPending(null)}\n />\n )}\n </>\n )\n}\n","import { useEffect, useRef, useState } from \"react\"\nimport { ArrowUp, X } from \"lucide-react\"\n\ninterface AnnotationFormProps {\n xPercent: number\n yPercent: number\n onSubmit: (text: string) => void\n onCancel: () => void\n}\n\nexport function AnnotationForm({ xPercent, yPercent, onSubmit, onCancel }: AnnotationFormProps) {\n const [text, setText] = useState(\"\")\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n useEffect(() => {\n textareaRef.current?.focus()\n }, [])\n\n const handleSubmit = () => {\n const trimmed = text.trim()\n if (!trimmed) return\n onSubmit(trimmed)\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault()\n handleSubmit()\n }\n if (e.key === \"Escape\") {\n onCancel()\n }\n e.stopPropagation()\n }\n\n // Position the form, flipping if near edges\n const left = xPercent > 70 ? undefined : `${xPercent}%`\n const right = xPercent > 70 ? `${100 - xPercent}%` : undefined\n const top = yPercent > 70 ? undefined : `${yPercent}%`\n const bottom = yPercent > 70 ? `${100 - yPercent}%` : undefined\n\n return (\n <div\n role=\"dialog\"\n className=\"absolute z-40 w-72 overflow-hidden rounded-xl border border-white/[0.08] bg-neutral-900/95 shadow-2xl backdrop-blur-2xl\"\n style={{ left, right, top, bottom }}\n onClick={e => e.stopPropagation()}\n onKeyDown={e => e.stopPropagation()}\n >\n <div className=\"flex items-center justify-between border-b border-white/[0.06] px-3.5 py-2.5\">\n <span className=\"text-xs font-medium tracking-wide text-neutral-400\">Add annotation</span>\n <button\n onClick={onCancel}\n className=\"rounded-lg p-1 text-neutral-500 transition-colors hover:bg-white/[0.06] hover:text-neutral-300\"\n >\n <X className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"p-3\">\n <textarea\n ref={textareaRef}\n value={text}\n onChange={e => setText(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Describe the change you want...\"\n className=\"w-full resize-none rounded-lg border border-white/[0.08] bg-white/[0.04] px-3 py-2 text-sm text-white placeholder-neutral-500 outline-none transition-colors focus:border-[#FF6B35]/50 focus:bg-white/[0.06]\"\n rows={3}\n />\n <div className=\"mt-2.5 flex items-center justify-between\">\n <span className=\"text-[11px] text-neutral-600\">Enter to send</span>\n <button\n onClick={handleSubmit}\n disabled={!text.trim()}\n className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-[#FF6B35] text-white shadow-lg shadow-[#FF6B35]/20 transition-all hover:bg-[#FF7A4A] hover:shadow-[#FF6B35]/30 disabled:opacity-30 disabled:shadow-none disabled:hover:bg-[#FF6B35]\"\n >\n <ArrowUp className=\"h-3.5 w-3.5\" strokeWidth={2.5} />\n </button>\n </div>\n </div>\n </div>\n )\n}\n","interface AnnotationPinProps {\n number: number\n status: \"open\" | \"resolved\"\n xPercent: number\n yPercent: number\n isSelected: boolean\n onClick: () => void\n}\n\nexport function AnnotationPin({ number, status, xPercent, yPercent, isSelected, onClick }: AnnotationPinProps) {\n const isResolved = status === \"resolved\"\n\n return (\n <button\n onClick={e => {\n e.stopPropagation()\n onClick()\n }}\n className=\"absolute z-30 -translate-x-1/2 -translate-y-1/2 transition-all duration-200 hover:scale-110\"\n style={{ left: `${xPercent}%`, top: `${yPercent}%` }}\n title={`Annotation #${number}`}\n >\n {/* Glow ring */}\n {isSelected && !isResolved && (\n <div className=\"absolute inset-[-4px] animate-pulse rounded-full bg-[#FF6B35]/25 blur-sm\" />\n )}\n <div\n className={`relative flex h-7 w-7 items-center justify-center rounded-full text-[11px] font-semibold shadow-lg backdrop-blur-sm transition-all duration-200 ${\n isSelected\n ? isResolved\n ? \"bg-neutral-500/90 text-white ring-2 ring-neutral-400/50\"\n : \"bg-[#FF6B35] text-white ring-2 ring-[#FF6B35]/40 ring-offset-1 ring-offset-black/50\"\n : isResolved\n ? \"bg-neutral-700/80 text-neutral-400\"\n : \"bg-[#FF6B35]/90 text-white hover:bg-[#FF6B35]\"\n }`}\n >\n {number}\n </div>\n </button>\n )\n}\n","import type { AnnotationTarget } from \"./types\"\n\n/**\n * Build a composite target descriptor from a clicked DOM element.\n */\nexport function buildElementTarget(\n element: HTMLElement,\n slideRoot: HTMLElement\n): AnnotationTarget {\n const rect = element.getBoundingClientRect()\n const rootRect = slideRoot.getBoundingClientRect()\n\n const xPercent = ((rect.left + rect.width / 2 - rootRect.left) / rootRect.width) * 100\n const yPercent = ((rect.top + rect.height / 2 - rootRect.top) / rootRect.height) * 100\n\n return {\n dataAnnotate: element.getAttribute(\"data-annotate\") || undefined,\n contentNearPin: getTextFingerprint(element),\n position: { xPercent, yPercent }\n }\n}\n\n/**\n * Resolve a stored target back to a DOM element, trying strategies in priority order.\n */\nexport function resolveTarget(\n target: AnnotationTarget,\n slideRoot: HTMLElement\n): { element: HTMLElement | null; method: \"dataAnnotate\" | \"contentNearPin\" | \"position\" } {\n // 1. Try data-annotate attribute\n if (target.dataAnnotate) {\n const el = slideRoot.querySelector<HTMLElement>(`[data-annotate=\"${target.dataAnnotate}\"]`)\n if (el) return { element: el, method: \"dataAnnotate\" }\n }\n\n // 2. Try text content match\n if (target.contentNearPin) {\n const match = findByTextContent(slideRoot, target.contentNearPin)\n if (match) return { element: match, method: \"contentNearPin\" }\n }\n\n // 3. Fallback to coordinates (no element found)\n return { element: null, method: \"position\" }\n}\n\n/**\n * Extract a text fingerprint from an element (first 100 chars, trimmed).\n */\nfunction getTextFingerprint(element: HTMLElement): string | undefined {\n const text = element.textContent?.trim()\n if (!text) return undefined\n return text.slice(0, 100)\n}\n\n/**\n * Find an element by matching its text content.\n */\nfunction findByTextContent(root: HTMLElement, text: string): HTMLElement | null {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT)\n let best: HTMLElement | null = null\n let bestLength = Infinity\n\n while (walker.nextNode()) {\n const el = walker.currentNode as HTMLElement\n const elText = el.textContent?.trim()\n if (!elText) continue\n\n const elFingerprint = elText.slice(0, 100)\n if (elFingerprint === text && elText.length < bestLength) {\n best = el\n bestLength = elText.length\n }\n }\n\n return best\n}\n","import { Check, Pencil, PanelRightClose, RotateCcw, Trash2 } from \"lucide-react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nimport type { Annotation } from \"./types\"\n\ninterface AnnotationPanelProps {\n annotations: Annotation[]\n unlinkedAnnotations?: Annotation[]\n selectedId: string | null\n onSelect: (id: string) => void\n onHover: (id: string | null) => void\n onDelete: (id: string) => void\n onUpdate: (id: string, patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => void\n onClose: () => void\n}\n\nexport function AnnotationPanel({\n annotations,\n unlinkedAnnotations = [],\n selectedId,\n onSelect,\n onHover,\n onDelete,\n onUpdate,\n onClose\n}: AnnotationPanelProps) {\n const open = annotations.filter(a => a.status === \"open\")\n const resolved = annotations.filter(a => a.status === \"resolved\")\n const total = annotations.length + unlinkedAnnotations.length\n const numberFor = (annotation: Annotation) =>\n annotations.findIndex(a => a.id === annotation.id) + 1\n\n return (\n <div className=\"flex h-full w-80 max-w-[90vw] flex-shrink-0 flex-col border-l border-neutral-800 bg-neutral-950 text-white\">\n <div className=\"flex items-center justify-between border-b border-neutral-800 px-3 py-2\">\n <button\n onClick={onClose}\n className=\"rounded p-2 text-neutral-400 hover:bg-neutral-800 hover:text-white\"\n aria-label=\"Hide comments\"\n title=\"Hide comments (C)\"\n >\n <PanelRightClose className=\"h-4 w-4\" />\n </button>\n <span className=\"text-right text-sm font-semibold\">Comments ({total})</span>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto p-3\">\n {annotations.length === 0 && unlinkedAnnotations.length === 0 && (\n <div className=\"flex flex-col gap-4 px-3 py-6\">\n <WorkflowHint />\n </div>\n )}\n\n {open.length > 0 && (\n <div>\n <div className=\"mb-1.5 px-2 pt-1 text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">\n Open\n </div>\n {open.map(a => (\n <AnnotationItem\n key={a.id}\n annotation={a}\n number={numberFor(a)}\n isSelected={a.id === selectedId}\n onSelect={() => onSelect(a.id)}\n onHover={hovered => onHover(hovered ? a.id : null)}\n onDelete={() => onDelete(a.id)}\n onUpdate={patch => onUpdate(a.id, patch)}\n />\n ))}\n </div>\n )}\n\n {resolved.length > 0 && (\n <div className={open.length > 0 ? \"mt-3\" : \"\"}>\n <div className=\"mb-1.5 px-2 pt-1 text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">\n Resolved\n </div>\n {resolved.map(a => (\n <AnnotationItem\n key={a.id}\n annotation={a}\n number={numberFor(a)}\n isSelected={a.id === selectedId}\n onSelect={() => onSelect(a.id)}\n onHover={hovered => onHover(hovered ? a.id : null)}\n onDelete={() => onDelete(a.id)}\n onUpdate={patch => onUpdate(a.id, patch)}\n />\n ))}\n </div>\n )}\n {unlinkedAnnotations.length > 0 && (\n <div className=\"mt-3\">\n <div className=\"mb-1.5 px-2 pt-1 text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">\n Removed slides\n </div>\n {unlinkedAnnotations.map((a, i) => (\n <div key={a.id}>\n <p className=\"px-2 text-[11px] text-neutral-500\">{a.slideTitle || a.slideId}</p>\n <AnnotationItem\n annotation={a}\n number={i + 1}\n isSelected={a.id === selectedId}\n onSelect={() => onSelect(a.id)}\n onHover={hovered => onHover(hovered ? a.id : null)}\n onDelete={() => onDelete(a.id)}\n onUpdate={patch => onUpdate(a.id, patch)}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n\n {annotations.length + unlinkedAnnotations.length > 0 && (\n <>\n <div className=\"border-t border-neutral-800\" />\n <div className=\"px-3 py-3\">\n <WorkflowHint />\n </div>\n </>\n )}\n </div>\n )\n}\n\nfunction WorkflowHint() {\n return (\n <div className=\"flex flex-col gap-2\">\n <p className=\"text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">Workflow</p>\n <div className=\"flex items-start gap-2.5\">\n <div className=\"mt-0.5 flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-[#FF6B35]/15 text-[10px] font-semibold text-[#FF6B35]\">\n 1\n </div>\n <p className=\"text-[12px] leading-snug text-neutral-400\">\n Comment on everything you want to fix\n </p>\n </div>\n <div className=\"flex items-start gap-2.5\">\n <div className=\"mt-0.5 flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-[#FF6B35]/15 text-[10px] font-semibold text-[#FF6B35]\">\n 2\n </div>\n <p className=\"text-[12px] leading-snug text-neutral-400\">Switch to your coding agent</p>\n </div>\n <div className=\"flex items-start gap-2.5\">\n <div className=\"mt-0.5 flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-[#FF6B35]/15 text-[10px] font-semibold text-[#FF6B35]\">\n 3\n </div>\n <p className=\"text-[12px] leading-snug text-neutral-400\">\"Fix open comments\"</p>\n </div>\n </div>\n )\n}\n\nfunction AnnotationItem({\n annotation,\n number,\n isSelected,\n onSelect,\n onHover,\n onDelete,\n onUpdate\n}: {\n annotation: Annotation\n number: number\n isSelected: boolean\n onSelect: () => void\n onHover: (hovered: boolean) => void\n onDelete: () => void\n onUpdate: (patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => void\n}) {\n const [isEditing, setIsEditing] = useState(false)\n const [draft, setDraft] = useState(annotation.body)\n const editRef = useRef<HTMLTextAreaElement>(null)\n useEffect(() => {\n if (isEditing) editRef.current?.focus()\n }, [isEditing])\n const saveEdit = () => {\n const body = draft.trim()\n if (!body) return\n if (body !== annotation.body) onUpdate({ body })\n setIsEditing(false)\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onSelect}\n onMouseEnter={() => onHover(true)}\n onMouseLeave={() => onHover(false)}\n onKeyDown={e => {\n if (e.target === e.currentTarget && (e.key === \"Enter\" || e.key === \" \")) onSelect()\n }}\n className={`group relative mb-0.5 cursor-pointer rounded-xl p-2.5 transition-all duration-150 ${\n isSelected ? \"bg-[#FF6B35]/10 ring-1 ring-[#FF6B35]/20\" : \"hover:bg-white/[0.04]\"\n }`}\n >\n <div className=\"absolute top-2 right-2 z-10 flex gap-0.5 rounded-full border border-neutral-700 bg-neutral-900/70 p-0.5 opacity-0 backdrop-blur-sm transition-opacity group-hover:opacity-100 group-focus-within:opacity-100\">\n <button\n type=\"button\"\n title=\"Edit comment\"\n aria-label=\"Edit comment\"\n onClick={e => {\n e.stopPropagation()\n setDraft(annotation.body)\n setIsEditing(true)\n }}\n className=\"rounded-full p-1 text-neutral-400 hover:bg-white/[0.08] hover:text-white\"\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n title={annotation.status === \"open\" ? \"Resolve comment\" : \"Reopen comment\"}\n aria-label={annotation.status === \"open\" ? \"Resolve comment\" : \"Reopen comment\"}\n onClick={e => {\n e.stopPropagation()\n onHover(false)\n onUpdate({ status: annotation.status === \"open\" ? \"resolved\" : \"open\" })\n }}\n className=\"rounded-full p-1 text-neutral-400 hover:bg-white/[0.08] hover:text-white\"\n >\n {annotation.status === \"open\" ? (\n <Check className=\"h-3.5 w-3.5\" />\n ) : (\n <RotateCcw className=\"h-3.5 w-3.5\" />\n )}\n </button>\n <button\n type=\"button\"\n title=\"Delete comment\"\n aria-label=\"Delete comment\"\n onClick={e => {\n e.stopPropagation()\n onDelete()\n }}\n className=\"rounded-full p-1 text-neutral-400 hover:bg-white/[0.08] hover:text-white\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"flex items-start gap-2.5\">\n <div\n className={`mt-0.5 flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full text-[11px] font-semibold ${\n annotation.status === \"open\"\n ? \"bg-[#FF6B35] text-white\"\n : \"bg-neutral-700 text-neutral-400\"\n }`}\n >\n {number}\n </div>\n <div className=\"min-w-0 flex-1 pr-4\">\n {isEditing ? (\n <div>\n <textarea\n ref={editRef}\n value={draft}\n onClick={e => e.stopPropagation()}\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === \"Escape\") setIsEditing(false)\n if ((e.metaKey || e.ctrlKey) && e.key === \"Enter\") saveEdit()\n }}\n className=\"w-full resize-y rounded border border-neutral-700 bg-neutral-900 p-2 text-[13px] text-white outline-none focus:border-[#FF6B35]\"\n rows={3}\n maxLength={4096}\n />\n <div className=\"mt-1 flex gap-2 text-xs\">\n <button\n type=\"button\"\n onClick={e => {\n e.stopPropagation()\n saveEdit()\n }}\n disabled={!draft.trim()}\n className=\"text-[#FF6B35] disabled:opacity-40\"\n >\n Save\n </button>\n <button\n type=\"button\"\n onClick={e => {\n e.stopPropagation()\n setIsEditing(false)\n }}\n className=\"text-neutral-400\"\n >\n Cancel\n </button>\n </div>\n </div>\n ) : (\n <p className=\"text-[13px] leading-relaxed text-neutral-200\">{annotation.body}</p>\n )}\n {annotation.target.contentNearPin && (\n <p className=\"mt-1 truncate text-[11px] text-neutral-600\">\n {annotation.target.contentNearPin}\n </p>\n )}\n {annotation.resolution && (\n <p className=\"mt-1.5 text-[11px] text-emerald-400/80 italic\">{annotation.resolution}</p>\n )}\n </div>\n </div>\n </div>\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport type { SlideConfig } from \"../types\"\nimport type { Annotation, AnnotationStorageAdapter, AnnotationTarget } from \"./types\"\n\nimport { createHttpAdapter } from \"./adapters/http\"\n\nexport function useAnnotations(\n slidesOrAdapter?: SlideConfig[] | AnnotationStorageAdapter,\n adapter?: AnnotationStorageAdapter\n) {\n const slides = Array.isArray(slidesOrAdapter) ? slidesOrAdapter : undefined\n const storage = Array.isArray(slidesOrAdapter) ? adapter : (slidesOrAdapter ?? adapter)\n const adapterRef = useRef(storage ?? createHttpAdapter())\n const slidesRef = useRef(slides)\n slidesRef.current = slides\n const [annotations, setAnnotations] = useState<Annotation[]>([])\n\n // Load on mount and subscribe to external updates\n useEffect(() => {\n adapterRef.current.load().then(loaded => {\n const configuredSlides = slidesRef.current\n const migrated = loaded.map(annotation => {\n if (annotation.slideId || !configuredSlides) return annotation\n const id = configuredSlides[annotation.slideIndex]?.id\n return id ? { ...annotation, slideId: id } : annotation\n })\n setAnnotations(migrated)\n if (migrated.some((annotation, index) => annotation !== loaded[index])) {\n void adapterRef.current.replaceAll?.(migrated)\n }\n })\n return adapterRef.current.subscribe?.(setAnnotations)\n }, [])\n\n const addAnnotation = useCallback(\n (\n slideIndex: number,\n slideTitle: string,\n target: AnnotationTarget,\n body: string,\n slideId?: string\n ) => {\n const annotation: Annotation = {\n id: crypto.randomUUID(),\n slideIndex,\n ...(slideId && { slideId }),\n slideTitle,\n target,\n body,\n createdAt: new Date().toISOString(),\n status: \"open\"\n }\n setAnnotations(prev => [...prev, annotation])\n adapterRef.current.add(annotation)\n },\n []\n )\n\n const deleteAnnotation = useCallback((id: string) => {\n setAnnotations(prev => prev.filter(a => a.id !== id))\n adapterRef.current.remove(id)\n }, [])\n\n const updateAnnotation = useCallback(\n (id: string, patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => {\n const current = annotations.find(a => a.id === id)\n if (!current) return\n const updated = { body: patch.body ?? current.body, status: patch.status ?? current.status }\n setAnnotations(prev => prev.map(a => (a.id === id ? { ...a, ...updated } : a)))\n void adapterRef.current.update?.(id, updated)\n },\n [annotations]\n )\n\n const getSlideAnnotations = useCallback(\n (slideIndex: number) => annotations.filter(a => a.slideIndex === slideIndex),\n [annotations]\n )\n\n const openCount = useMemo(\n () => annotations.filter(a => a.status === \"open\").length,\n [annotations]\n )\n\n // Allow external state updates (e.g. from postMessage adapter)\n const updateAnnotations = useCallback((updated: Annotation[]) => {\n setAnnotations(updated)\n }, [])\n\n return {\n annotations,\n addAnnotation,\n deleteAnnotation,\n updateAnnotation,\n getSlideAnnotations,\n openCount,\n updateAnnotations\n }\n}\n","import type { Annotation, AnnotationsFile, AnnotationStorageAdapter } from \"../types\"\n\nconst ENDPOINT = \"/__promptslide_annotations\"\n\nasync function loadAll(): Promise<Annotation[]> {\n try {\n const res = await fetch(ENDPOINT)\n if (!res.ok) return []\n const data: AnnotationsFile = await res.json()\n return data.annotations || []\n } catch {\n return []\n }\n}\n\nasync function saveAll(annotations: Annotation[]): Promise<void> {\n const data: AnnotationsFile = { version: 1, annotations }\n await fetch(ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data)\n })\n}\n\n/** Storage adapter for local Vite dev server (reads/writes annotations.json via middleware) */\nexport function createHttpAdapter(): AnnotationStorageAdapter {\n let cache: Annotation[] = []\n\n return {\n async load() {\n cache = await loadAll()\n return cache\n },\n async add(annotation) {\n cache = [...cache, annotation]\n await saveAll(cache)\n },\n async remove(id) {\n cache = cache.filter(a => a.id !== id)\n await saveAll(cache)\n },\n async update(id, patch) {\n cache = cache.map(a => (a.id === id ? { ...a, ...patch } : a))\n await saveAll(cache)\n },\n async replaceAll(annotations) {\n cache = annotations\n await saveAll(cache)\n }\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","motion","jsx","jsx","motion","useCallback","useEffect","useState","jsx","useState","useEffect","useCallback","useCallback","useEffect","useMemo","useRef","useState","useCallback","useEffect","useRef","useState","useEffect","useRef","useState","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useRef","useCallback","useEffect","useEffect","useRef","useState","Fragment","jsx","jsxs","useCallback","useEffect","useMemo","useRef","useState","useRef","useState","useEffect","useCallback","useMemo","Fragment","jsx","jsxs","useRef","useState","useEffect","useMemo","useCallback"]}
|
|
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/slide-renderer.tsx","../src/core/slide-error-boundary.tsx","../src/core/slide-embed.tsx","../src/core/slide-deck.tsx","../src/core/annotations/annotation-overlay.tsx","../src/core/annotations/annotation-form.tsx","../src/core/annotations/annotation-pin.tsx","../src/core/annotations/selectors.ts","../src/core/annotations/annotation-panel.tsx","../src/core/annotations/use-annotations.ts","../src/core/annotations/adapters/http.ts","../src/core/inspector.tsx","../src/core/utils.ts","../src/core/loop/config.mjs","../src/core/loop/context.tsx","../src/core/loop/loop-settings.tsx","../src/core/loop/use-loop-playback.ts","../src/core/toolbar-action.tsx","../src/core/view-menu.tsx"],"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 (0 = visible from slide entry) */\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={isVisible ? false : \"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={isVisible ? false : \"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 // Render the next slide fully beneath the current one, then fade the\n // outgoing slide away. This keeps the frame opaque throughout the change.\n enter: { opacity: 1, zIndex: 0 },\n center: { opacity: 1, zIndex: 0 },\n exit: { opacity: 0, zIndex: 1 }\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, useRef, 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\nconst POSITION_KEY = \"promptslide:position\"\n\nfunction slideKey(slides: SlideConfig[], index: number): string {\n return slides[index]?.id || String(index + 1)\n}\n\nfunction slideFromHash(slides: SlideConfig[]): number | null {\n if (typeof window === \"undefined\" || !window.location.hash) return null\n let hash: string\n try {\n hash = decodeURIComponent(window.location.hash.slice(1))\n } catch {\n return null\n }\n const byId = slides.findIndex(slide => slide.id === hash)\n if (byId >= 0) return byId\n if (/^[1-9]\\d*$/.test(hash)) {\n const index = Number(hash) - 1\n if (index < slides.length) return index\n }\n return null\n}\n\nfunction savedStep(slides: SlideConfig[], index: number): number {\n if (typeof window === \"undefined\") return 0\n try {\n const saved = JSON.parse(window.sessionStorage.getItem(POSITION_KEY) || \"null\")\n if (saved?.slide === slideKey(slides, index) && Number.isInteger(saved.step)) {\n return Math.max(0, Math.min(saved.step, slides[index]?.steps ?? 0))\n }\n } catch {\n /* Storage may be unavailable. */\n }\n return 0\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 goToStep: (step: number) => void\n restartAtSlide: (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(() => slideFromHash(slides) ?? initialSlide)\n const [animationStep, setAnimationStep] = useState(() =>\n savedStep(slides, slideFromHash(slides) ?? initialSlide)\n )\n const slidesRef = useRef(slides)\n const activeKeyRef = useRef(slideKey(slides, slideFromHash(slides) ?? initialSlide))\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 useEffect(() => {\n if (typeof window === \"undefined\" || slides.length === 0) return\n if (slidesRef.current !== slides) {\n slidesRef.current = slides\n const previousKey = activeKeyRef.current\n const movedIndex = slides.findIndex(slide => slide.id && slide.id === previousKey)\n if (movedIndex >= 0 && movedIndex !== currentSlide) {\n setCurrentSlide(movedIndex)\n return\n }\n if (movedIndex < 0 && !/^[1-9]\\d*$/.test(previousKey) && currentSlide !== 0) {\n setAnimationStep(0)\n setCurrentSlide(0)\n return\n }\n }\n if (!slides[currentSlide]) {\n setCurrentSlide(0)\n setAnimationStep(0)\n return\n }\n const key = slideKey(slides, currentSlide)\n activeKeyRef.current = key\n const hash = `#${encodeURIComponent(key)}`\n if (window.location.hash !== hash) {\n window.history.replaceState(window.history.state, \"\", hash)\n }\n try {\n window.sessionStorage.setItem(\n POSITION_KEY,\n JSON.stringify({ slide: key, step: animationStep })\n )\n } catch {\n /* Storage may be unavailable. */\n }\n }, [slides, currentSlide, animationStep])\n\n useEffect(() => {\n const handleHashChange = () => {\n const index = slideFromHash(slides) ?? 0\n if (index === currentSlide) return\n setNavState({ status: \"transitioning\", direction: index > currentSlide ? 1 : -1 })\n setAnimationStep(0)\n setCurrentSlide(index)\n onSlideChange?.(index)\n }\n window.addEventListener(\"hashchange\", handleHashChange)\n return () => window.removeEventListener(\"hashchange\", handleHashChange)\n }, [slides, currentSlide, onSlideChange])\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 const goToStep = useCallback(\n (step: number) => {\n if (!Number.isInteger(step)) return\n setQueuedAction(null)\n setAnimationStep(Math.max(0, Math.min(step, slides[currentSlide]?.steps ?? 0)))\n setNavState(previous => ({ ...previous, direction: 0 }))\n },\n [slides, currentSlide]\n )\n\n const restartAtSlide = useCallback(\n (index: number) => {\n if (index < 0 || index >= slides.length) return\n setQueuedAction(null)\n setAnimationStep(0)\n setCurrentSlide(index)\n // Same-slide restarts do not have a transition to complete.\n setNavState({ status: index === currentSlide ? \"idle\" : \"transitioning\", direction: 1 })\n onSlideChange?.(index)\n },\n [slides.length, currentSlide, 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 goToStep,\n restartAtSlide,\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 { 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 playbackKey?: number\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 playbackKey,\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 data-slide-render-index={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 slideIndex={currentSlide} slideTitle={slides[currentSlide]?.title}>\n <CurrentSlideComponent\n key={playbackKey}\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 fit viewport while preserving aspect ratio\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=\"h-screen w-screen overflow-hidden bg-black\">\n <div\n className=\"absolute left-1/2 top-1/2 overflow-hidden\"\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n transform: `translate(-50%, -50%) 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 {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Download,\n MessageCircle,\n PanelLeftClose,\n PanelLeftOpen,\n Play,\n Settings2\n} from \"lucide-react\"\nimport { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\"\n\nimport type { Annotation, AnnotationTarget } from \"./annotations\"\nimport type { SlideTransitionType } from \"./transitions\"\nimport type { LoopConfig, SlideConfig } from \"./types\"\n\nimport { SLIDE_DIMENSIONS } from \"./animation-config\"\nimport { AnimationProvider } from \"./animation-context\"\nimport { AnnotationOverlay, AnnotationPanel, useAnnotations } from \"./annotations\"\nimport { Inspector, type InspectorMode } from \"./inspector\"\nimport {\n DEFAULT_LOOP_CONFIG,\n includedSlides,\n loopSlideKey,\n validateLoopConfig\n} from \"./loop/config.mjs\"\nimport { useDefaultLoopConfig } from \"./loop/context\"\nimport { LoopSettings } from \"./loop/loop-settings\"\nimport { useLoopPlayback } from \"./loop/use-loop-playback\"\nimport { SlideErrorBoundary } from \"./slide-error-boundary\"\nimport { SlideRenderer } from \"./slide-renderer\"\nimport { ToolbarAction } from \"./toolbar-action\"\nimport { useSlideNavigation } from \"./use-slide-navigation\"\nimport { cn } from \"./utils\"\nimport { ViewMenu, type ViewMode } from \"./view-menu\"\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nconst NARROW_VIEWPORT_WIDTH = 768\nconst DEFAULT_THUMBNAIL_WIDTH = 240\nconst MIN_THUMBNAIL_WIDTH = 176\nconst MAX_THUMBNAIL_WIDTH = 480\nconst THUMBNAIL_WIDTH_STORAGE_KEY = \"promptslide:thumbnail-width\"\n\nfunction loadLoopConfig(base: LoopConfig, storageKey: string): LoopConfig {\n let fallback = DEFAULT_LOOP_CONFIG\n try {\n fallback = validateLoopConfig(base)\n } catch {\n /* Invalid host settings use defaults. */\n }\n try {\n const saved = JSON.parse(localStorage.getItem(storageKey) || \"null\")\n if (saved?.base === JSON.stringify(base)) return validateLoopConfig(saved.config)\n } catch {\n /* Storage may be disabled or stale. */\n }\n return fallback\n}\n\nfunction GridThumbnail({\n slide,\n index,\n total\n}: {\n slide: SlideConfig\n index: number\n total: number\n}) {\n const viewportRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLDivElement>(null)\n const SlideComponent = slide.component\n\n useLayoutEffect(() => {\n const viewport = viewportRef.current\n const canvas = canvasRef.current\n if (!viewport || !canvas) return\n const resize = () => {\n canvas.style.transform = `scale(${viewport.clientWidth / SLIDE_DIMENSIONS.width})`\n }\n resize()\n const observer = new ResizeObserver(resize)\n observer.observe(viewport)\n return () => observer.disconnect()\n }, [])\n\n return (\n <div ref={viewportRef} className=\"absolute inset-0 overflow-hidden\">\n <div\n ref={canvasRef}\n className=\"absolute top-0 left-0 origin-top-left\"\n style={{ width: SLIDE_DIMENSIONS.width, height: SLIDE_DIMENSIONS.height }}\n >\n <AnimationProvider currentStep={slide.steps} totalSteps={slide.steps} showAllAnimations>\n <SlideErrorBoundary slideIndex={index} slideTitle={slide.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={total} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n </div>\n )\n}\n\nfunction ListSlide({ slide, index, total }: { slide: SlideConfig; index: number; total: number }) {\n const viewportRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLDivElement>(null)\n const SlideComponent = slide.component\n\n useLayoutEffect(() => {\n const viewport = viewportRef.current\n const canvas = canvasRef.current\n if (!viewport || !canvas) return\n const resize = () => {\n canvas.style.transform = `scale(${viewport.clientWidth / SLIDE_DIMENSIONS.width})`\n }\n resize()\n const observer = new ResizeObserver(resize)\n observer.observe(viewport)\n return () => observer.disconnect()\n }, [])\n\n return (\n <div\n ref={viewportRef}\n className=\"relative aspect-video w-full overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-sm print:m-0 print:h-[1080px] print:w-[1920px] print:break-after-page print:rounded-none print:border-0 print:shadow-none\"\n >\n <div\n ref={canvasRef}\n className=\"list-slide-canvas absolute top-0 left-0 origin-top-left\"\n style={{ width: SLIDE_DIMENSIONS.width, height: SLIDE_DIMENSIONS.height }}\n >\n <AnimationProvider currentStep={slide.steps} totalSteps={slide.steps} showAllAnimations>\n <SlideErrorBoundary slideIndex={index} slideTitle={slide.title}>\n <SlideComponent slideNumber={index + 1} totalSlides={total} />\n </SlideErrorBoundary>\n </AnimationProvider>\n </div>\n </div>\n )\n}\n\ninterface SlideDeckProps {\n slides: SlideConfig[]\n transition?: SlideTransitionType\n directionalTransition?: boolean\n /** Overrides the CLI-provided loop settings. */\n loopConfig?: LoopConfig\n /** Persist settings in a custom host. CLI Studio saves loop-config.json automatically. */\n onLoopConfigChange?: (config: LoopConfig) => void | Promise<void>\n /** Annotation data to display. When provided (even empty array), annotation UI is enabled. When undefined, annotation UI is hidden. */\n annotations?: Annotation[]\n /** Called when the user creates an annotation */\n onAnnotationAdd?: (\n slideIndex: number,\n slideTitle: string,\n target: AnnotationTarget,\n body: string,\n slideId?: string\n ) => void\n /** Called when the user deletes an annotation */\n onAnnotationDelete?: (id: string) => void\n onAnnotationUpdate?: (id: string, patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => void\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 let cancelled = false\n const markReady = async () => {\n await document.fonts.ready\n await Promise.all(Array.from(document.images, image => image.decode().catch(() => {})))\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n if (!cancelled) setReady(true)\n })\n )\n }\n void markReady()\n return () => {\n cancelled = true\n }\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({\n slides,\n transition,\n directionalTransition,\n loopConfig: suppliedLoopConfig,\n onLoopConfigChange,\n annotations,\n onAnnotationAdd,\n onAnnotationDelete,\n onAnnotationUpdate\n}: 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 // Use internal useAnnotations as fallback when no external annotations prop is provided\n const internal = useAnnotations(slides)\n const isExternallyManaged = annotations !== undefined\n const effectiveAnnotations = isExternallyManaged ? annotations : internal.annotations\n const effectiveAdd = isExternallyManaged ? onAnnotationAdd : internal.addAnnotation\n const effectiveDelete = isExternallyManaged ? onAnnotationDelete : internal.deleteAnnotation\n const effectiveUpdate = isExternallyManaged ? onAnnotationUpdate : internal.updateAnnotation\n\n const openCount = useMemo(\n () => effectiveAnnotations.filter(a => a.status === \"open\").length,\n [effectiveAnnotations]\n )\n const getSlideAnnotations = useCallback(\n (slideIndex: number) =>\n effectiveAnnotations.filter(a =>\n a.slideId ? a.slideId === slides[slideIndex]?.id : a.slideIndex === slideIndex\n ),\n [effectiveAnnotations, slides]\n )\n const unlinkedAnnotations = useMemo(\n () =>\n effectiveAnnotations.filter(a => a.slideId && !slides.some(slide => slide.id === a.slideId)),\n [effectiveAnnotations, slides]\n )\n\n const [viewMode, setViewMode] = useState<ViewMode>(\"slide\")\n const [isEditorOpen, setIsEditorOpen] = useState(false)\n const editorOpenRef = useRef(false)\n const [editorAvailable, setEditorAvailable] = useState(false)\n const [inspectorMode, setInspectorMode] = useState<InspectorMode | null>(null)\n const pendingInspector = useRef<InspectorMode | null | undefined>(undefined)\n const [editorRevision, setEditorRevision] = useState(0)\n const activateInspector = useCallback((mode: InspectorMode | null) => {\n setInspectorMode(mode)\n setLoopMenuOpen(false)\n if (mode) setViewMode(\"slide\")\n if (mode !== \"comments\") {\n setSelectedAnnotationId(null)\n setHoveredAnnotationId(null)\n }\n }, [])\n const requestInspector = useCallback(\n (mode: InspectorMode | null) => {\n if (isEditorOpen) {\n if (mode === \"editor\") return\n pendingInspector.current = mode\n window.dispatchEvent(\n new CustomEvent(\"promptslide:editor-request\", { detail: { open: false } })\n )\n return\n }\n if (mode === \"editor\") {\n if (editorAvailable)\n window.dispatchEvent(\n new CustomEvent(\"promptslide:editor-request\", { detail: { open: true } })\n )\n return\n }\n activateInspector(mode)\n },\n [isEditorOpen, editorAvailable, activateInspector]\n )\n useEffect(() => {\n const onEditorState = (event: Event) => {\n const open = Boolean((event as CustomEvent).detail?.open)\n const changed = editorOpenRef.current !== open\n editorOpenRef.current = open\n setIsEditorOpen(open)\n if (open) {\n if (changed) pendingInspector.current = undefined\n activateInspector(\"editor\")\n } else if (changed) {\n const next = pendingInspector.current\n pendingInspector.current = undefined\n activateInspector(next === undefined ? null : next)\n }\n }\n const onEditorReady = (event: Event) =>\n setEditorAvailable(Boolean((event as CustomEvent).detail?.available))\n const onCloseCancelled = () => {\n pendingInspector.current = undefined\n }\n const refreshEditor = () => setEditorRevision(value => value + 1)\n window.addEventListener(\"promptslide:editor-state\", onEditorState)\n window.addEventListener(\"promptslide:editor-ready\", onEditorReady)\n window.addEventListener(\"promptslide:editor-close-cancelled\", onCloseCancelled)\n window.addEventListener(\"promptslide:editor-refresh\", refreshEditor)\n return () => {\n window.removeEventListener(\"promptslide:editor-state\", onEditorState)\n window.removeEventListener(\"promptslide:editor-ready\", onEditorReady)\n window.removeEventListener(\"promptslide:editor-close-cancelled\", onCloseCancelled)\n window.removeEventListener(\"promptslide:editor-refresh\", refreshEditor)\n }\n }, [activateInspector])\n const [isPresentationMode, setIsPresentationMode] = useState(false)\n const providedLoopConfig = useDefaultLoopConfig()\n const defaultLoopKey = JSON.stringify(suppliedLoopConfig ?? providedLoopConfig)\n const defaultLoopConfig = useMemo<LoopConfig>(() => JSON.parse(defaultLoopKey), [defaultLoopKey])\n const storageKey = `promptslide:loop:${typeof location === \"undefined\" ? \"\" : location.pathname}:${JSON.stringify(slides.map(loopSlideKey))}`\n const [loopConfig, setLoopConfig] = useState<LoopConfig>(() =>\n loadLoopConfig(defaultLoopConfig, storageKey)\n )\n const [loopDraft, setLoopDraft] = useState<LoopConfig>(() =>\n loadLoopConfig(defaultLoopConfig, storageKey)\n )\n const [playbackConfig, setPlaybackConfig] = useState(loopConfig)\n const [isLooping, setIsLooping] = useState(false)\n const [loopMenuOpen, setLoopMenuOpen] = useState(false)\n const [loopError, setLoopError] = useState(\"\")\n const [loopStartScreen, setLoopStartScreen] = useState(\n () => typeof window !== \"undefined\" && new URLSearchParams(window.location.search).has(\"loop\")\n )\n const loopMenuRef = useRef<HTMLDivElement>(null)\n useEffect(() => {\n const config = loadLoopConfig(defaultLoopConfig, storageKey)\n setLoopConfig(config)\n setLoopDraft(config)\n setPlaybackConfig(config)\n setIsLooping(false)\n }, [defaultLoopConfig, storageKey])\n useEffect(() => {\n if (!loopMenuOpen) return\n const close = (event: PointerEvent) => {\n if (!loopMenuRef.current?.contains(event.target as Node)) setLoopMenuOpen(false)\n }\n document.addEventListener(\"pointerdown\", close)\n return () => document.removeEventListener(\"pointerdown\", close)\n }, [loopMenuOpen])\n const [viewportWidth, setViewportWidth] = useState(() =>\n typeof window === \"undefined\" ? 1280 : window.innerWidth\n )\n const [showThumbnailRail, setShowThumbnailRail] = useState(() =>\n typeof window === \"undefined\" ? true : window.innerWidth >= NARROW_VIEWPORT_WIDTH\n )\n const [thumbnailWidth, setThumbnailWidth] = useState(() => {\n if (typeof window === \"undefined\") return DEFAULT_THUMBNAIL_WIDTH\n const savedWidth = Number(window.localStorage.getItem(THUMBNAIL_WIDTH_STORAGE_KEY))\n return Number.isFinite(savedWidth) && savedWidth >= MIN_THUMBNAIL_WIDTH\n ? Math.min(savedWidth, MAX_THUMBNAIL_WIDTH)\n : DEFAULT_THUMBNAIL_WIDTH\n })\n const isAnnotationMode = inspectorMode === \"comments\"\n const [selectedAnnotationId, setSelectedAnnotationId] = useState<string | null>(null)\n const [hoveredAnnotationId, setHoveredAnnotationId] = useState<string | null>(null)\n const [isResizingThumbnails, setIsResizingThumbnails] = useState(false)\n const [isDragCollapsed, setIsDragCollapsed] = useState(false)\n const [isAnimatingDragBoundary, setIsAnimatingDragBoundary] = useState(false)\n const [scale, setScale] = useState(1)\n const containerRef = useRef<HTMLDivElement>(null)\n const slideContainerRef = useRef<HTMLDivElement>(null)\n const previewViewportRef = useRef<HTMLDivElement>(null)\n const activeThumbnailRef = useRef<HTMLButtonElement>(null)\n const preferredRailOpenRef = useRef(true)\n const wasNarrowViewportRef = useRef(viewportWidth < NARROW_VIEWPORT_WIDTH)\n const resizeStartRef = useRef<{\n pointerId: number\n pointerX: number\n width: number\n } | null>(null)\n const previousUserSelectRef = useRef(\"\")\n const previousCursorRef = useRef(\"\")\n const dragCollapsedRef = useRef(false)\n const dragAnimationTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const isNarrowViewport = viewportWidth < NARROW_VIEWPORT_WIDTH\n const maxThumbnailWidth = isNarrowViewport\n ? Math.max(120, Math.floor(viewportWidth * 0.8))\n : Math.min(MAX_THUMBNAIL_WIDTH, viewportWidth - 360)\n const minThumbnailWidth = Math.min(MIN_THUMBNAIL_WIDTH, maxThumbnailWidth)\n const visibleThumbnailWidth = Math.min(thumbnailWidth, maxThumbnailWidth)\n const isThumbnailRailVisible = showThumbnailRail && !isDragCollapsed\n\n const setThumbnailRailOpen = useCallback((open: boolean) => {\n preferredRailOpenRef.current = open\n setShowThumbnailRail(open)\n }, [])\n\n useEffect(() => {\n const handleResize = () => setViewportWidth(window.innerWidth)\n window.addEventListener(\"resize\", handleResize)\n return () => window.removeEventListener(\"resize\", handleResize)\n }, [])\n\n useEffect(() => {\n if (isNarrowViewport !== wasNarrowViewportRef.current) {\n setShowThumbnailRail(isNarrowViewport ? false : preferredRailOpenRef.current)\n if (isNarrowViewport) {\n setInspectorMode(mode => (mode === \"comments\" ? null : mode))\n setSelectedAnnotationId(null)\n }\n wasNarrowViewportRef.current = isNarrowViewport\n }\n }, [isNarrowViewport])\n\n useEffect(() => {\n window.localStorage.setItem(THUMBNAIL_WIDTH_STORAGE_KEY, String(thumbnailWidth))\n }, [thumbnailWidth])\n\n useEffect(\n () => () => {\n if (resizeStartRef.current) {\n document.body.style.userSelect = previousUserSelectRef.current\n document.body.style.cursor = previousCursorRef.current\n }\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n },\n []\n )\n\n useEffect(() => {\n if (\n (!showThumbnailRail || isPresentationMode || viewMode !== \"slide\") &&\n resizeStartRef.current\n ) {\n resizeStartRef.current = null\n dragCollapsedRef.current = false\n setIsResizingThumbnails(false)\n setIsDragCollapsed(false)\n setIsAnimatingDragBoundary(false)\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n document.body.style.userSelect = previousUserSelectRef.current\n document.body.style.cursor = previousCursorRef.current\n }\n }, [showThumbnailRail, isPresentationMode, viewMode])\n\n useEffect(() => {\n if (!isResizingThumbnails) return\n\n const getDraggedWidth = (clientX: number) => {\n const start = resizeStartRef.current\n return start ? start.width + clientX - start.pointerX : null\n }\n const handlePointerMove = (event: PointerEvent) => {\n if (event.pointerId !== resizeStartRef.current?.pointerId) return\n const nextWidth = getDraggedWidth(event.clientX)\n if (nextWidth === null) return\n const collapsed = nextWidth < minThumbnailWidth\n if (collapsed !== dragCollapsedRef.current) {\n dragCollapsedRef.current = collapsed\n setIsDragCollapsed(collapsed)\n setIsAnimatingDragBoundary(true)\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n dragAnimationTimerRef.current = setTimeout(() => {\n setIsAnimatingDragBoundary(false)\n dragAnimationTimerRef.current = null\n }, 200)\n }\n if (!collapsed) setThumbnailWidth(Math.min(maxThumbnailWidth, nextWidth))\n }\n const stopResize = (event?: PointerEvent) => {\n if (event && event.pointerId !== resizeStartRef.current?.pointerId) return\n const nextWidth = event ? getDraggedWidth(event.clientX) : null\n const collapsed =\n event?.type === \"pointerup\" && nextWidth !== null && nextWidth < minThumbnailWidth\n resizeStartRef.current = null\n dragCollapsedRef.current = false\n document.body.style.userSelect = previousUserSelectRef.current\n document.body.style.cursor = previousCursorRef.current\n setIsResizingThumbnails(false)\n setIsDragCollapsed(false)\n if (collapsed) setThumbnailRailOpen(false)\n else if (nextWidth !== null) {\n setThumbnailWidth(Math.max(minThumbnailWidth, Math.min(maxThumbnailWidth, nextWidth)))\n }\n }\n const handleBlur = () => stopResize()\n\n window.addEventListener(\"pointermove\", handlePointerMove)\n window.addEventListener(\"pointerup\", stopResize)\n window.addEventListener(\"pointercancel\", stopResize)\n window.addEventListener(\"blur\", handleBlur)\n return () => {\n window.removeEventListener(\"pointermove\", handlePointerMove)\n window.removeEventListener(\"pointerup\", stopResize)\n window.removeEventListener(\"pointercancel\", stopResize)\n window.removeEventListener(\"blur\", handleBlur)\n }\n }, [isResizingThumbnails, minThumbnailWidth, maxThumbnailWidth, setThumbnailRailOpen])\n\n const {\n currentSlide,\n animationStep,\n totalSteps,\n isTransitioning,\n direction,\n showAllAnimations,\n advance,\n goBack,\n goToSlide,\n goToStep,\n restartAtSlide,\n onTransitionComplete\n } = useSlideNavigation({\n slides\n })\n\n const playback = useLoopPlayback({\n config: playbackConfig,\n slides,\n currentSlide,\n animationStep,\n isTransitioning,\n enabled: isLooping && isPresentationMode,\n advance,\n goBack,\n restartAtSlide\n })\n const rememberLoopConfig = (config: LoopConfig) => {\n setLoopConfig(config)\n setLoopDraft(config)\n try {\n localStorage.setItem(\n storageKey,\n JSON.stringify({ base: JSON.stringify(defaultLoopConfig), config })\n )\n return true\n } catch {\n return false\n }\n }\n const saveLoopConfig = async (config: LoopConfig) => {\n if (onLoopConfigChange) {\n await onLoopConfigChange(config)\n rememberLoopConfig(config)\n return \"Loop settings saved.\"\n }\n try {\n const response = await fetch(\"/__promptslide_loop\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(config)\n })\n if (response.status === 204) {\n rememberLoopConfig(config)\n return \"Saved to loop-config.json. Included in future builds and publishing.\"\n }\n if (response.status !== 404 && response.status !== 405)\n throw new Error(\n \"Studio could not save loop-config.json. Download the settings to keep a copy.\"\n )\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Studio\")) throw error\n }\n return rememberLoopConfig(config)\n ? \"Saved in this browser. Download settings and place loop-config.json in the project folder to share or publish them.\"\n : \"Applied for this session. Browser storage is unavailable; download the settings to keep them.\"\n }\n const startLoop = async (config = loopDraft) => {\n if (isEditorOpen) return\n const first = includedSlides(config, slides)[0]\n if (first === undefined) {\n setLoopError(\"Include at least one slide before starting the loop.\")\n return\n }\n setLoopError(\"\")\n try {\n // Request synchronously from the click, before any asynchronous work.\n if (!document.fullscreenElement) await document.documentElement.requestFullscreen()\n setPlaybackConfig(config)\n setLoopDraft(config)\n setViewMode(\"slide\")\n setInspectorMode(null)\n setLoopMenuOpen(false)\n setLoopStartScreen(false)\n playback.setPaused(false)\n playback.restart(first)\n setIsLooping(true)\n } catch {\n setLoopError(\n \"Full screen could not start. Allow full screen in your browser, then try again.\"\n )\n }\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 if (!document.fullscreenElement) setIsLooping(false)\n }\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange)\n return () => document.removeEventListener(\"fullscreenchange\", handleFullscreenChange)\n }, [])\n\n useEffect(() => {\n if (viewMode === \"slide\" && !isPresentationMode && showThumbnailRail) {\n activeThumbnailRef.current?.scrollIntoView({ block: \"nearest\" })\n }\n }, [currentSlide, isPresentationMode, showThumbnailRail, viewMode])\n\n // Calculate scale factor for presentation mode\n useEffect(() => {\n const calculateScale = () => {\n if (!isPresentationMode) {\n setScale(1)\n return\n }\n const availableWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n const scaleX = availableWidth / 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 // Keep slide layout at its design size; only scale the rendered canvas.\n useLayoutEffect(() => {\n const viewport = previewViewportRef.current\n const canvas = slideContainerRef.current\n if (!viewport || !canvas) return\n const resize = (width: number, height: number) => {\n const fitScale = Math.min(width / SLIDE_DIMENSIONS.width, height / SLIDE_DIMENSIONS.height)\n canvas.style.transform = `scale(${fitScale})`\n }\n resize(viewport.clientWidth, viewport.clientHeight)\n const observer = new ResizeObserver(([entry]) => {\n if (!entry) return\n resize(entry.contentRect.width, entry.contentRect.height)\n })\n observer.observe(viewport)\n return () => observer.disconnect()\n }, [viewMode, isPresentationMode])\n\n const toggleCommentMode = useCallback(() => {\n requestInspector(isAnnotationMode && viewMode === \"slide\" ? null : \"comments\")\n }, [isAnnotationMode, viewMode, requestInspector])\n\n const handleExportPdf = useCallback(async () => {\n try {\n const response = await fetch(\"/__promptslide_pdf\")\n if (response.ok && response.headers.get(\"content-type\")?.includes(\"application/pdf\")) {\n const blob = await response.blob()\n const url = URL.createObjectURL(blob)\n const link = document.createElement(\"a\")\n link.href = url\n link.download = \"slides.pdf\"\n link.click()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n return\n }\n } catch {\n /* Static builds use the browser print fallback. */\n }\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 }, [viewMode])\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null\n if (target?.closest(\"input, textarea, [contenteditable='true']\")) return\n if (e.altKey || e.ctrlKey || e.metaKey) return\n const key = e.key.toLowerCase()\n if (e.repeat && \"fvglcdt\".includes(key)) return\n if (isEditorOpen && [\"f\", \"v\", \"g\", \"l\", \"c\", \"d\"].includes(key)) return\n\n if (loopStartScreen) return\n if (loopMenuOpen) {\n if (e.key === \"Escape\") {\n setLoopMenuOpen(false)\n loopMenuRef.current?.querySelector(\"button\")?.focus()\n }\n return\n }\n if (isLooping) {\n if (e.key === \"Escape\") {\n setIsLooping(false)\n if (document.fullscreenElement) void document.exitFullscreen().catch(() => {})\n } else if (e.key === \" \") {\n e.preventDefault()\n if (!e.repeat) playback.setPaused(value => !value)\n } else if (e.key === \"ArrowRight\" || e.key === \"ArrowLeft\") {\n e.preventDefault()\n playback.move(e.key === \"ArrowRight\" ? 1 : -1)\n }\n return\n }\n\n if (key === \"f\") {\n e.preventDefault()\n void togglePresentationMode()\n return\n }\n\n if (key === \"v\" && !isPresentationMode) {\n e.preventDefault()\n setViewMode(\"slide\")\n return\n }\n\n if (key === \"g\") {\n e.preventDefault()\n setViewMode(prev => (prev === \"grid\" ? \"slide\" : \"grid\"))\n return\n }\n\n if (key === \"l\") {\n e.preventDefault()\n setViewMode(prev => (prev === \"list\" ? \"slide\" : \"list\"))\n return\n }\n\n if (key === \"c\" && !isPresentationMode) {\n e.preventDefault()\n toggleCommentMode()\n return\n }\n\n if (key === \"d\" && !isPresentationMode) {\n e.preventDefault()\n void handleExportPdf()\n return\n }\n\n if (viewMode === \"slide\" && !isPresentationMode && key === \"t\") {\n e.preventDefault()\n setThumbnailRailOpen(!showThumbnailRail)\n return\n }\n\n if (viewMode !== \"slide\" || (isAnnotationMode && !isPresentationMode)) 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 }, [\n advance,\n goBack,\n playback,\n isLooping,\n loopMenuOpen,\n loopStartScreen,\n viewMode,\n togglePresentationMode,\n isAnnotationMode,\n isEditorOpen,\n isPresentationMode,\n setThumbnailRailOpen,\n showThumbnailRail,\n toggleCommentMode,\n handleExportPdf\n ])\n\n const inspectorWidth = viewportWidth <= 850 ? 280 : 320\n const inspectorVisible = inspectorMode !== null && !isPresentationMode && viewMode === \"slide\"\n\n return (\n <div className=\"min-h-screen w-full bg-neutral-950 text-foreground\">\n <style>{`\n .slide-thumbnail-scroll-area {\n scrollbar-width: thin;\n scrollbar-color: #404040 transparent;\n }\n .slide-thumbnail-scroll-area::-webkit-scrollbar {\n width: 10px;\n }\n .slide-thumbnail-scroll-area::-webkit-scrollbar-track {\n background: transparent;\n }\n .slide-thumbnail-scroll-area::-webkit-scrollbar-thumb {\n background-color: #404040;\n border: 3px solid transparent;\n border-radius: 9999px;\n background-clip: padding-box;\n }\n .slide-thumbnail-scroll-area::-webkit-scrollbar-thumb:hover {\n background-color: #525252;\n }\n .slide-thumbnail-scroll-area::-webkit-scrollbar-corner {\n background: transparent;\n }\n @media print {\n .list-slide-canvas {\n transform: scale(1.5) !important;\n }\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 {loopError && (\n <div\n role=\"alert\"\n className=\"fixed bottom-4 left-4 z-[110] max-w-md rounded-lg border border-red-700 bg-neutral-950 p-4 text-sm text-red-300\"\n >\n {loopError}\n <button className=\"ml-3 underline\" onClick={() => setLoopError(\"\")}>\n Dismiss\n </button>\n </div>\n )}\n {loopStartScreen && (\n <div className=\"fixed inset-0 z-[90] flex flex-col items-center justify-center gap-5 bg-neutral-950 text-white\">\n <h1 className=\"text-3xl font-semibold\">Ready to loop</h1>\n <p className=\"text-neutral-400\">Space pauses or resumes. Escape stops the loop.</p>\n <button\n className=\"rounded-lg border border-orange-500 px-6 py-3 text-orange-400\"\n onClick={() => void startLoop()}\n >\n Click to start\n </button>\n <button\n className=\"text-sm text-neutral-400 underline\"\n onClick={() => {\n setLoopStartScreen(false)\n requestInspector(\"slide\")\n }}\n >\n Configure loop\n </button>\n </div>\n )}\n {isLooping && playback.paused && (\n <div\n role=\"status\"\n className=\"pointer-events-none fixed bottom-4 left-4 z-[90] rounded-md bg-neutral-950 px-4 py-2 text-sm text-white\"\n >\n Loop paused · Space to resume\n </div>\n )}\n\n {/* Toolbar */}\n <div\n data-ps-viewer-toolbar\n style={\n inspectorVisible\n ? { right: inspectorWidth + 16, maxWidth: `calc(100vw - ${inspectorWidth + 32}px)` }\n : undefined\n }\n className={cn(\n \"fixed top-4 z-50 flex flex-wrap gap-1 rounded-lg border border-neutral-800 bg-neutral-950/90 p-1 backdrop-blur-sm transition-[right] duration-200 ease-out print:hidden\",\n (isPresentationMode || (isNarrowViewport && inspectorVisible && !isEditorOpen)) &&\n \"hidden\",\n isEditorOpen && viewportWidth <= 850 && \"[&_button:disabled]:hidden [&>div]:hidden\",\n !inspectorVisible && \"right-4\"\n )}\n >\n <ViewMenu value={viewMode} onChange={setViewMode} disabled={isEditorOpen} />\n\n <div className=\"mx-1 w-px bg-neutral-800\" />\n\n <ToolbarAction\n onClick={toggleCommentMode}\n label=\"Comment\"\n selected={isAnnotationMode}\n title=\"Comment (C)\"\n >\n <MessageCircle className=\"h-[15px] w-[15px] shrink-0\" />\n {openCount > 0 && (\n <span className=\"absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-[#FF6B35] text-[10px] font-bold text-white\">\n {openCount}\n </span>\n )}\n </ToolbarAction>\n\n <span data-ps-editor-toolbar className=\"contents\" />\n <ToolbarAction\n label=\"Slide settings\"\n selected={inspectorMode === \"slide\" && inspectorVisible}\n onClick={() =>\n requestInspector(inspectorMode === \"slide\" && inspectorVisible ? null : \"slide\")\n }\n >\n <Settings2 size={16} />\n </ToolbarAction>\n\n <div className=\"mx-1 w-px bg-neutral-800\" />\n\n <ToolbarAction\n onClick={handleExportPdf}\n disabled={isEditorOpen}\n label=\"Download PDF\"\n title=\"Download PDF (D)\"\n >\n <Download className=\"h-4 w-4\" />\n </ToolbarAction>\n <div ref={loopMenuRef} className=\"relative flex\">\n <button\n onClick={togglePresentationMode}\n className=\"inline-flex h-8 items-center justify-center gap-1.5 rounded-l-md border border-[#FF6B35]/50 bg-[#FF6B35]/15 px-3 text-sm font-semibold text-[#FF6B35] transition-colors hover:border-[#FF6B35] hover:bg-[#FF6B35]/25\"\n disabled={isEditorOpen}\n title=\"Present (F)\"\n >\n <Play className=\"h-3.5 w-3.5 fill-current\" />\n <span>Present</span>\n </button>\n <button\n disabled={isEditorOpen}\n aria-label=\"Presentation options\"\n aria-expanded={loopMenuOpen}\n aria-controls=\"presentation-options\"\n className=\"rounded-r-md border border-l-0 border-[#FF6B35]/50 bg-[#FF6B35]/15 px-2 text-[#FF6B35] hover:bg-[#FF6B35]/25\"\n onClick={() => setLoopMenuOpen(value => !value)}\n >\n <ChevronDown size={16} />\n </button>\n {loopMenuOpen && (\n <div\n id=\"presentation-options\"\n className=\"absolute right-0 top-10 w-52 rounded-lg border border-neutral-700 bg-neutral-950 p-1 text-sm text-white\"\n >\n <button\n className=\"w-full rounded px-3 py-2 text-left hover:bg-neutral-800\"\n onClick={() => void startLoop()}\n >\n Auto-loop\n </button>\n <button\n className=\"w-full rounded px-3 py-2 text-left hover:bg-neutral-800\"\n onClick={() => {\n setLoopMenuOpen(false)\n requestInspector(\"slide\")\n }}\n >\n Configure loop…\n </button>\n </div>\n )}\n </div>\n </div>\n\n {/* Slide View */}\n {viewMode === \"slide\" && (\n <div\n className={cn(\"flex h-screen w-full print:hidden\", isPresentationMode ? \"bg-black\" : \"\")}\n >\n {!isPresentationMode && (\n <>\n <div\n className={cn(\n \"relative z-10 h-screen shrink-0\",\n isNarrowViewport && \"fixed inset-y-0 left-0\",\n isResizingThumbnails && !isAnimatingDragBoundary\n ? \"transition-none\"\n : \"transition-[width] duration-200 ease-out motion-reduce:transition-none\"\n )}\n style={{ width: isThumbnailRailVisible ? visibleThumbnailWidth : 0 }}\n >\n <div className=\"h-full w-full overflow-hidden\">\n <aside\n id=\"presentation-thumbnails\"\n aria-label=\"Slide thumbnails\"\n aria-hidden={!isThumbnailRailVisible}\n inert={!isThumbnailRailVisible}\n className={cn(\n \"flex h-screen shrink-0 flex-col border-r border-neutral-800 bg-neutral-950 text-white transition-opacity motion-reduce:transition-none\",\n isThumbnailRailVisible\n ? \"opacity-100 delay-100 duration-100\"\n : \"opacity-0 duration-75\"\n )}\n style={{ width: visibleThumbnailWidth }}\n >\n <div className=\"flex items-center justify-between border-b border-neutral-800 px-3 py-2\">\n <span className=\"text-sm font-semibold\">Slides ({slides.length})</span>\n <button\n type=\"button\"\n onClick={() => setThumbnailRailOpen(false)}\n className=\"rounded p-2 text-neutral-400 hover:bg-neutral-800 hover:text-white\"\n aria-label=\"Hide slide thumbnails\"\n title=\"Hide thumbnails (T)\"\n >\n <PanelLeftClose className=\"h-4 w-4\" />\n </button>\n </div>\n <div className=\"slide-thumbnail-scroll-area min-h-0 flex-1 space-y-3 overflow-y-auto p-3\">\n {slides.map((slideConfig, index) => (\n <button\n key={slideConfig.id ?? index}\n ref={index === currentSlide ? activeThumbnailRef : undefined}\n type=\"button\"\n onClick={() => goToSlide(index)}\n aria-label={`Go to slide ${index + 1}${slideConfig.title ? `: ${slideConfig.title}` : \"\"}`}\n aria-current={index === currentSlide ? \"page\" : undefined}\n className={cn(\n \"block w-full rounded-lg border p-1.5 text-left transition-colors focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#FF6B35]\",\n index === currentSlide\n ? \"border-[#FF6B35] bg-[#FF6B35]/15 ring-1 ring-[#FF6B35]\"\n : \"border-transparent hover:border-neutral-600 hover:bg-neutral-800\"\n )}\n >\n <div className=\"relative aspect-video w-full overflow-hidden rounded bg-black\">\n {loopDraft.slides[loopSlideKey(slideConfig, index)]?.excluded && (\n <span className=\"absolute right-1 top-1 z-10 rounded border border-neutral-700 bg-neutral-950 px-1.5 py-0.5 text-[9px] text-neutral-400\">\n Skip in loop\n </span>\n )}\n <GridThumbnail\n slide={slideConfig}\n index={index}\n total={slides.length}\n />\n </div>\n <div className=\"mt-1.5 flex items-baseline gap-2 px-0.5 text-xs\">\n {slideConfig.title ? (\n <>\n <span className=\"font-mono text-neutral-400\">{index + 1}</span>\n <span className=\"truncate\">{slideConfig.title}</span>\n </>\n ) : (\n <span>Slide {index + 1}</span>\n )}\n </div>\n </button>\n ))}\n </div>\n </aside>\n </div>\n {isThumbnailRailVisible && (\n <div\n role=\"separator\"\n aria-label=\"Resize slide thumbnails\"\n aria-orientation=\"vertical\"\n aria-valuemin={minThumbnailWidth}\n aria-valuemax={maxThumbnailWidth}\n aria-valuenow={visibleThumbnailWidth}\n tabIndex={0}\n className={cn(\n \"absolute inset-y-0 -right-1 w-2 cursor-col-resize touch-none focus-visible:outline-none after:pointer-events-none after:absolute after:inset-y-0 after:right-1 after:w-0.5 after:bg-transparent after:content-[''] after:transition-colors hover:after:bg-[#FF6B35]/50 focus-visible:after:bg-[#FF6B35]/50\",\n isResizingThumbnails && \"after:bg-[#FF6B35]/60\"\n )}\n onPointerDown={event => {\n if (event.button !== 0) return\n event.preventDefault()\n resizeStartRef.current = {\n pointerId: event.pointerId,\n pointerX: event.clientX,\n width: visibleThumbnailWidth\n }\n dragCollapsedRef.current = false\n setIsAnimatingDragBoundary(false)\n if (dragAnimationTimerRef.current) clearTimeout(dragAnimationTimerRef.current)\n setIsResizingThumbnails(true)\n previousUserSelectRef.current = document.body.style.userSelect\n previousCursorRef.current = document.body.style.cursor\n document.body.style.userSelect = \"none\"\n document.body.style.cursor = \"col-resize\"\n }}\n onKeyDown={event => {\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") {\n event.preventDefault()\n event.stopPropagation()\n const amount = event.key === \"ArrowRight\" ? 16 : -16\n setThumbnailWidth(\n Math.max(\n minThumbnailWidth,\n Math.min(maxThumbnailWidth, visibleThumbnailWidth + amount)\n )\n )\n }\n }}\n />\n )}\n </div>\n <div\n aria-hidden={isThumbnailRailVisible || isResizingThumbnails}\n inert={isThumbnailRailVisible || isResizingThumbnails}\n className={cn(\n \"fixed left-4 z-50 rounded-lg border border-neutral-800 bg-neutral-950/90 backdrop-blur-sm transition-opacity duration-150 motion-reduce:transition-none\",\n isNarrowViewport && !inspectorVisible ? \"top-16\" : \"top-4\",\n isThumbnailRailVisible || isResizingThumbnails\n ? \"pointer-events-none opacity-0\"\n : \"opacity-100 delay-200\"\n )}\n >\n <button\n type=\"button\"\n onClick={() => setThumbnailRailOpen(true)}\n className=\"rounded-md p-2 text-neutral-400 transition-colors hover:bg-neutral-800 hover:text-white\"\n aria-label=\"Show slide thumbnails\"\n title=\"Show thumbnails (T)\"\n >\n <PanelLeftOpen className=\"h-4 w-4\" />\n </button>\n </div>\n </>\n )}\n <div\n ref={containerRef}\n role=\"presentation\"\n data-loop-running={isLooping ? \"true\" : undefined}\n tabIndex={isPresentationMode ? 0 : undefined}\n className={cn(\n \"flex min-w-0 flex-1 flex-col items-center justify-center overflow-hidden\",\n isPresentationMode ? `bg-black p-0 ${isLooping ? \"cursor-none\" : \"\"}` : \"p-4 md:p-8\"\n )}\n onClick={\n isPresentationMode ? () => (isLooping ? playback.move(1) : advance()) : undefined\n }\n onKeyDown={\n isPresentationMode\n ? e => {\n if (e.key === \"Enter\") {\n e.preventDefault()\n e.stopPropagation()\n if (isLooping) playback.move(1)\n else advance()\n }\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 playbackKey={isLooping ? playback.epoch : undefined}\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\n ref={previewViewportRef}\n className=\"relative aspect-video w-full max-w-7xl overflow-hidden rounded-xl border border-neutral-800 bg-black shadow-2xl\"\n >\n <div\n ref={slideContainerRef}\n data-ps-editor-canvas\n tabIndex={-1}\n data-slide-index={currentSlide}\n className=\"absolute top-0 left-0 overflow-hidden outline-none\"\n style={{\n width: SLIDE_DIMENSIONS.width,\n height: SLIDE_DIMENSIONS.height,\n transformOrigin: \"top left\"\n }}\n >\n <SlideRenderer\n key={editorRevision}\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 {isAnnotationMode && (\n <AnnotationOverlay\n slides={slides}\n currentSlide={currentSlide}\n slideContainerRef={slideContainerRef}\n selectedId={selectedAnnotationId}\n hoveredId={hoveredAnnotationId}\n onSelectId={setSelectedAnnotationId}\n onShowPanel={() => requestInspector(\"comments\")}\n slideAnnotations={getSlideAnnotations(currentSlide)}\n addAnnotation={effectiveAdd ?? (() => {})}\n />\n )}\n </div>\n <div\n data-ps-editor-overlay\n className=\"pointer-events-none absolute inset-0 z-20\"\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 title=\"Previous step or slide (←)\"\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 </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 title=\"Next step or slide (→ / Space)\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </div>\n )}\n </div>\n\n <Inspector\n mode={inspectorMode}\n visible={inspectorVisible}\n editorAvailable={editorAvailable}\n width={inspectorWidth}\n overlay={isNarrowViewport}\n onSelect={requestInspector}\n onClose={() => requestInspector(null)}\n slideSettings={\n <LoopSettings\n slides={slides}\n currentSlide={currentSlide}\n animationStep={animationStep}\n config={loopDraft}\n onChange={setLoopDraft}\n onStepChange={goToStep}\n onSave={saveLoopConfig}\n onStart={config => void startLoop(config)}\n onRevert={() => setLoopDraft(loopConfig)}\n dirty={JSON.stringify(loopDraft) !== JSON.stringify(loopConfig)}\n />\n }\n comments={\n <AnnotationPanel\n embedded\n annotations={getSlideAnnotations(currentSlide)}\n unlinkedAnnotations={unlinkedAnnotations}\n selectedId={selectedAnnotationId}\n onSelect={setSelectedAnnotationId}\n onHover={setHoveredAnnotationId}\n onDelete={effectiveDelete ?? (() => {})}\n onUpdate={effectiveUpdate ?? (() => {})}\n onClose={() => requestInspector(null)}\n />\n }\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 prevSection = index > 0 ? slides[index - 1]?.section : undefined\n const showSectionHeader = slideConfig.section && slideConfig.section !== prevSection\n\n return (\n <div key={slideConfig.id ?? index} className=\"contents\">\n {showSectionHeader && (\n <h3 className=\"col-span-full mt-4 mb-0 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-[#FF6B35] hover:shadow-lg hover:shadow-[#FF6B35]/10\"\n >\n <GridThumbnail slide={slideConfig} index={index} total={slides.length} />\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 <ListSlide\n key={slideConfig.id ?? index}\n slide={slideConfig}\n index={index}\n total={slides.length}\n />\n ))}\n </div>\n </div>\n </div>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nimport type { SlideConfig } from \"../types\"\nimport type { Annotation, AnnotationTarget } from \"./types\"\n\nimport { AnnotationForm } from \"./annotation-form\"\nimport { AnnotationPin } from \"./annotation-pin\"\nimport { buildElementTarget, resolveTarget } from \"./selectors\"\n\ninterface AnnotationOverlayProps {\n slides: SlideConfig[]\n currentSlide: number\n /** Ref to the slide container element (the div wrapping SlideRenderer) */\n slideContainerRef: React.RefObject<HTMLDivElement | null>\n selectedId: string | null\n hoveredId: string | null\n onSelectId: (id: string | null) => void\n onShowPanel: () => void\n slideAnnotations: Annotation[]\n addAnnotation: (\n slideIndex: number,\n slideTitle: string,\n target: AnnotationTarget,\n body: string,\n slideId?: string\n ) => void\n}\n\ninterface PendingAnnotation {\n target: AnnotationTarget\n xPercent: number\n yPercent: number\n}\n\nexport function AnnotationOverlay({\n slides,\n currentSlide,\n slideContainerRef,\n selectedId,\n hoveredId,\n onSelectId,\n onShowPanel,\n slideAnnotations,\n addAnnotation\n}: AnnotationOverlayProps) {\n const [pending, setPending] = useState<PendingAnnotation | null>(null)\n const [hoveredElement, setHoveredElement] = useState<DOMRect | null>(null)\n const overlayRef = useRef<HTMLDivElement>(null)\n\n const slideTitle = slides[currentSlide]?.title || `Slide ${currentSlide + 1}`\n\n // Resolve annotation positions — use the element if found, otherwise fallback coordinates\n const resolvedAnnotations = slideAnnotations.map((a, i) => {\n const container = slideContainerRef.current\n if (!container) {\n return {\n annotation: a,\n xPercent: a.target.position.xPercent,\n yPercent: a.target.position.yPercent,\n number: i + 1\n }\n }\n\n const { element } = resolveTarget(a.target, container)\n if (element) {\n const rect = element.getBoundingClientRect()\n const containerRect = container.getBoundingClientRect()\n const xPercent =\n ((rect.left + rect.width / 2 - containerRect.left) / containerRect.width) * 100\n const yPercent =\n ((rect.top + rect.height / 2 - containerRect.top) / containerRect.height) * 100\n return { annotation: a, xPercent, yPercent, number: i + 1 }\n }\n\n return {\n annotation: a,\n xPercent: a.target.position.xPercent,\n yPercent: a.target.position.yPercent,\n number: i + 1\n }\n })\n\n const handleOverlayClick = useCallback(\n (e: React.MouseEvent) => {\n const container = slideContainerRef.current\n if (!container) return\n\n // Get the element under the click by temporarily hiding the overlay\n const overlay = overlayRef.current\n if (overlay) overlay.style.pointerEvents = \"none\"\n const elementUnder = document.elementFromPoint(e.clientX, e.clientY) as HTMLElement | null\n if (overlay) overlay.style.pointerEvents = \"\"\n\n if (!elementUnder || !container.contains(elementUnder)) {\n setPending(null)\n onSelectId(null)\n return\n }\n\n // Pick the most specific meaningful element (skip tiny text nodes, pick their parent)\n let target = elementUnder\n if (\n target.tagName === \"SPAN\" &&\n target.parentElement &&\n container.contains(target.parentElement)\n ) {\n // For inline spans, prefer their parent for a more meaningful target\n const parent = target.parentElement\n if (parent.tagName !== \"DIV\" || parent.children.length <= 3) {\n target = parent\n }\n }\n\n const annotationTarget = buildElementTarget(target, container)\n const containerRect = container.getBoundingClientRect()\n const xPercent = ((e.clientX - containerRect.left) / containerRect.width) * 100\n const yPercent = ((e.clientY - containerRect.top) / containerRect.height) * 100\n\n setPending({ target: annotationTarget, xPercent, yPercent })\n onSelectId(null)\n },\n [slideContainerRef, onSelectId]\n )\n\n const handleSubmit = useCallback(\n (text: string) => {\n if (!pending) return\n addAnnotation(currentSlide, slideTitle, pending.target, text, slides[currentSlide]?.id)\n setPending(null)\n onShowPanel()\n },\n [pending, currentSlide, slideTitle, slides, addAnnotation, onShowPanel]\n )\n\n // Track hover for element highlighting\n const handleMouseMove = useCallback(\n (e: React.MouseEvent) => {\n if (pending) {\n setHoveredElement(null)\n return\n }\n\n const container = slideContainerRef.current\n if (!container) return\n\n const overlay = overlayRef.current\n if (overlay) overlay.style.pointerEvents = \"none\"\n const elementUnder = document.elementFromPoint(e.clientX, e.clientY) as HTMLElement | null\n if (overlay) overlay.style.pointerEvents = \"\"\n\n if (elementUnder && container.contains(elementUnder) && elementUnder !== container) {\n const containerRect = container.getBoundingClientRect()\n const elRect = elementUnder.getBoundingClientRect()\n const scaleX = containerRect.width / container.offsetWidth\n const scaleY = containerRect.height / container.offsetHeight\n setHoveredElement(\n new DOMRect(\n (elRect.left - containerRect.left) / scaleX,\n (elRect.top - containerRect.top) / scaleY,\n elRect.width / scaleX,\n elRect.height / scaleY\n )\n )\n } else {\n setHoveredElement(null)\n }\n },\n [slideContainerRef, pending]\n )\n\n // Clear pending when slide changes\n useEffect(() => {\n setPending(null)\n onSelectId(null)\n setHoveredElement(null)\n }, [currentSlide, onSelectId])\n\n return (\n <>\n {/* Hover highlight */}\n {hoveredElement && (\n <div\n className=\"pointer-events-none absolute z-20 rounded-lg border-2 border-dashed border-[#FF6B35]/50 bg-[#FF6B35]/5\"\n style={{\n left: hoveredElement.x,\n top: hoveredElement.y,\n width: hoveredElement.width,\n height: hoveredElement.height\n }}\n />\n )}\n\n {/* Click capture overlay */}\n <div\n ref={overlayRef}\n role=\"button\"\n tabIndex={0}\n className=\"absolute inset-0 z-20\"\n style={{\n cursor: `url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none'%3E%3Ccircle cx='12' cy='12' r='8' stroke='%23FF6B35' stroke-width='2' opacity='0.8'/%3E%3Ccircle cx='12' cy='12' r='2' fill='%23FF6B35'/%3E%3C/svg%3E\") 12 12, crosshair`\n }}\n onClick={handleOverlayClick}\n onKeyDown={e => {\n if (e.key === \"Escape\") {\n setPending(null)\n onSelectId(null)\n }\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setHoveredElement(null)}\n />\n\n {/* Annotation pins */}\n {resolvedAnnotations\n .filter(({ annotation }) => annotation.status === \"open\" || annotation.id === hoveredId)\n .map(({ annotation, xPercent, yPercent, number }) => (\n <AnnotationPin\n key={annotation.id}\n number={number}\n status={annotation.status}\n xPercent={xPercent}\n yPercent={yPercent}\n isSelected={annotation.id === selectedId}\n onClick={() => {\n onSelectId(annotation.id === selectedId ? null : annotation.id)\n onShowPanel()\n setPending(null)\n }}\n />\n ))}\n\n {/* New annotation form */}\n {pending && (\n <AnnotationForm\n xPercent={pending.xPercent}\n yPercent={pending.yPercent}\n onSubmit={handleSubmit}\n onCancel={() => setPending(null)}\n />\n )}\n </>\n )\n}\n","import { useEffect, useRef, useState } from \"react\"\nimport { ArrowUp, X } from \"lucide-react\"\n\ninterface AnnotationFormProps {\n xPercent: number\n yPercent: number\n onSubmit: (text: string) => void\n onCancel: () => void\n}\n\nexport function AnnotationForm({ xPercent, yPercent, onSubmit, onCancel }: AnnotationFormProps) {\n const [text, setText] = useState(\"\")\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n useEffect(() => {\n textareaRef.current?.focus()\n }, [])\n\n const handleSubmit = () => {\n const trimmed = text.trim()\n if (!trimmed) return\n onSubmit(trimmed)\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault()\n handleSubmit()\n }\n if (e.key === \"Escape\") {\n onCancel()\n }\n e.stopPropagation()\n }\n\n // Position the form, flipping if near edges\n const left = xPercent > 70 ? undefined : `${xPercent}%`\n const right = xPercent > 70 ? `${100 - xPercent}%` : undefined\n const top = yPercent > 70 ? undefined : `${yPercent}%`\n const bottom = yPercent > 70 ? `${100 - yPercent}%` : undefined\n\n return (\n <div\n role=\"dialog\"\n className=\"absolute z-40 w-72 overflow-hidden rounded-xl border border-white/[0.08] bg-neutral-900/95 shadow-2xl backdrop-blur-2xl\"\n style={{ left, right, top, bottom }}\n onClick={e => e.stopPropagation()}\n onKeyDown={e => e.stopPropagation()}\n >\n <div className=\"flex items-center justify-between border-b border-white/[0.06] px-3.5 py-2.5\">\n <span className=\"text-xs font-medium tracking-wide text-neutral-400\">Add annotation</span>\n <button\n onClick={onCancel}\n className=\"rounded-lg p-1 text-neutral-500 transition-colors hover:bg-white/[0.06] hover:text-neutral-300\"\n >\n <X className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"p-3\">\n <textarea\n ref={textareaRef}\n value={text}\n onChange={e => setText(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Describe the change you want...\"\n className=\"w-full resize-none rounded-lg border border-white/[0.08] bg-white/[0.04] px-3 py-2 text-sm text-white placeholder-neutral-500 outline-none transition-colors focus:border-[#FF6B35]/50 focus:bg-white/[0.06]\"\n rows={3}\n />\n <div className=\"mt-2.5 flex items-center justify-between\">\n <span className=\"text-[11px] text-neutral-600\">Enter to send</span>\n <button\n onClick={handleSubmit}\n disabled={!text.trim()}\n className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-[#FF6B35] text-white shadow-lg shadow-[#FF6B35]/20 transition-all hover:bg-[#FF7A4A] hover:shadow-[#FF6B35]/30 disabled:opacity-30 disabled:shadow-none disabled:hover:bg-[#FF6B35]\"\n >\n <ArrowUp className=\"h-3.5 w-3.5\" strokeWidth={2.5} />\n </button>\n </div>\n </div>\n </div>\n )\n}\n","interface AnnotationPinProps {\n number: number\n status: \"open\" | \"resolved\"\n xPercent: number\n yPercent: number\n isSelected: boolean\n onClick: () => void\n}\n\nexport function AnnotationPin({ number, status, xPercent, yPercent, isSelected, onClick }: AnnotationPinProps) {\n const isResolved = status === \"resolved\"\n\n return (\n <button\n onClick={e => {\n e.stopPropagation()\n onClick()\n }}\n className=\"absolute z-30 -translate-x-1/2 -translate-y-1/2 transition-all duration-200 hover:scale-110\"\n style={{ left: `${xPercent}%`, top: `${yPercent}%` }}\n title={`Annotation #${number}`}\n >\n {/* Glow ring */}\n {isSelected && !isResolved && (\n <div className=\"absolute inset-[-4px] animate-pulse rounded-full bg-[#FF6B35]/25 blur-sm\" />\n )}\n <div\n className={`relative flex h-7 w-7 items-center justify-center rounded-full text-[11px] font-semibold shadow-lg backdrop-blur-sm transition-all duration-200 ${\n isSelected\n ? isResolved\n ? \"bg-neutral-500/90 text-white ring-2 ring-neutral-400/50\"\n : \"bg-[#FF6B35] text-white ring-2 ring-[#FF6B35]/40 ring-offset-1 ring-offset-black/50\"\n : isResolved\n ? \"bg-neutral-700/80 text-neutral-400\"\n : \"bg-[#FF6B35]/90 text-white hover:bg-[#FF6B35]\"\n }`}\n >\n {number}\n </div>\n </button>\n )\n}\n","import type { AnnotationTarget } from \"./types\"\n\n/**\n * Build a composite target descriptor from a clicked DOM element.\n */\nexport function buildElementTarget(\n element: HTMLElement,\n slideRoot: HTMLElement\n): AnnotationTarget {\n const rect = element.getBoundingClientRect()\n const rootRect = slideRoot.getBoundingClientRect()\n\n const xPercent = ((rect.left + rect.width / 2 - rootRect.left) / rootRect.width) * 100\n const yPercent = ((rect.top + rect.height / 2 - rootRect.top) / rootRect.height) * 100\n\n return {\n dataAnnotate: element.getAttribute(\"data-annotate\") || undefined,\n contentNearPin: getTextFingerprint(element),\n position: { xPercent, yPercent }\n }\n}\n\n/**\n * Resolve a stored target back to a DOM element, trying strategies in priority order.\n */\nexport function resolveTarget(\n target: AnnotationTarget,\n slideRoot: HTMLElement\n): { element: HTMLElement | null; method: \"dataAnnotate\" | \"contentNearPin\" | \"position\" } {\n // 1. Try data-annotate attribute\n if (target.dataAnnotate) {\n const el = slideRoot.querySelector<HTMLElement>(`[data-annotate=\"${target.dataAnnotate}\"]`)\n if (el) return { element: el, method: \"dataAnnotate\" }\n }\n\n // 2. Try text content match\n if (target.contentNearPin) {\n const match = findByTextContent(slideRoot, target.contentNearPin)\n if (match) return { element: match, method: \"contentNearPin\" }\n }\n\n // 3. Fallback to coordinates (no element found)\n return { element: null, method: \"position\" }\n}\n\n/**\n * Extract a text fingerprint from an element (first 100 chars, trimmed).\n */\nfunction getTextFingerprint(element: HTMLElement): string | undefined {\n const text = element.textContent?.trim()\n if (!text) return undefined\n return text.slice(0, 100)\n}\n\n/**\n * Find an element by matching its text content.\n */\nfunction findByTextContent(root: HTMLElement, text: string): HTMLElement | null {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT)\n let best: HTMLElement | null = null\n let bestLength = Infinity\n\n while (walker.nextNode()) {\n const el = walker.currentNode as HTMLElement\n const elText = el.textContent?.trim()\n if (!elText) continue\n\n const elFingerprint = elText.slice(0, 100)\n if (elFingerprint === text && elText.length < bestLength) {\n best = el\n bestLength = elText.length\n }\n }\n\n return best\n}\n","import { Check, Pencil, PanelRightClose, RotateCcw, Trash2 } from \"lucide-react\"\nimport { useEffect, useRef, useState } from \"react\"\n\nimport type { Annotation } from \"./types\"\n\ninterface AnnotationPanelProps {\n embedded?: boolean\n annotations: Annotation[]\n unlinkedAnnotations?: Annotation[]\n selectedId: string | null\n onSelect: (id: string) => void\n onHover: (id: string | null) => void\n onDelete: (id: string) => void\n onUpdate: (id: string, patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => void\n onClose: () => void\n}\n\nexport function AnnotationPanel({\n embedded = false,\n annotations,\n unlinkedAnnotations = [],\n selectedId,\n onSelect,\n onHover,\n onDelete,\n onUpdate,\n onClose\n}: AnnotationPanelProps) {\n const open = annotations.filter(a => a.status === \"open\")\n const resolved = annotations.filter(a => a.status === \"resolved\")\n const total = annotations.length + unlinkedAnnotations.length\n const numberFor = (annotation: Annotation) =>\n annotations.findIndex(a => a.id === annotation.id) + 1\n\n return (\n <div\n className={`flex h-full max-w-[90vw] flex-shrink-0 flex-col bg-neutral-950 text-white ${embedded ? \"w-full\" : \"w-80 border-l border-neutral-800\"}`}\n >\n {!embedded && (\n <div className=\"flex items-center justify-between border-b border-neutral-800 px-3 py-2\">\n <button\n onClick={onClose}\n className=\"rounded p-2 text-neutral-400 hover:bg-neutral-800 hover:text-white\"\n aria-label=\"Hide comments\"\n title=\"Hide comments (C)\"\n >\n <PanelRightClose className=\"h-4 w-4\" />\n </button>\n <span className=\"text-right text-sm font-semibold\">Comments ({total})</span>\n </div>\n )}\n\n <div className=\"min-h-0 flex-1 overflow-y-auto p-3\">\n {annotations.length === 0 && unlinkedAnnotations.length === 0 && (\n <div className=\"flex flex-col gap-4 px-3 py-6\">\n <WorkflowHint />\n </div>\n )}\n\n {open.length > 0 && (\n <div>\n <div className=\"mb-1.5 px-2 pt-1 text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">\n Open\n </div>\n {open.map(a => (\n <AnnotationItem\n key={a.id}\n annotation={a}\n number={numberFor(a)}\n isSelected={a.id === selectedId}\n onSelect={() => onSelect(a.id)}\n onHover={hovered => onHover(hovered ? a.id : null)}\n onDelete={() => onDelete(a.id)}\n onUpdate={patch => onUpdate(a.id, patch)}\n />\n ))}\n </div>\n )}\n\n {resolved.length > 0 && (\n <div className={open.length > 0 ? \"mt-3\" : \"\"}>\n <div className=\"mb-1.5 px-2 pt-1 text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">\n Resolved\n </div>\n {resolved.map(a => (\n <AnnotationItem\n key={a.id}\n annotation={a}\n number={numberFor(a)}\n isSelected={a.id === selectedId}\n onSelect={() => onSelect(a.id)}\n onHover={hovered => onHover(hovered ? a.id : null)}\n onDelete={() => onDelete(a.id)}\n onUpdate={patch => onUpdate(a.id, patch)}\n />\n ))}\n </div>\n )}\n {unlinkedAnnotations.length > 0 && (\n <div className=\"mt-3\">\n <div className=\"mb-1.5 px-2 pt-1 text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">\n Removed slides\n </div>\n {unlinkedAnnotations.map((a, i) => (\n <div key={a.id}>\n <p className=\"px-2 text-[11px] text-neutral-500\">{a.slideTitle || a.slideId}</p>\n <AnnotationItem\n annotation={a}\n number={i + 1}\n isSelected={a.id === selectedId}\n onSelect={() => onSelect(a.id)}\n onHover={hovered => onHover(hovered ? a.id : null)}\n onDelete={() => onDelete(a.id)}\n onUpdate={patch => onUpdate(a.id, patch)}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n\n {annotations.length + unlinkedAnnotations.length > 0 && (\n <>\n <div className=\"border-t border-neutral-800\" />\n <div className=\"px-3 py-3\">\n <WorkflowHint />\n </div>\n </>\n )}\n </div>\n )\n}\n\nfunction WorkflowHint() {\n return (\n <div className=\"flex flex-col gap-2\">\n <p className=\"text-[11px] font-medium tracking-wider text-neutral-500 uppercase\">Workflow</p>\n <div className=\"flex items-start gap-2.5\">\n <div className=\"mt-0.5 flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-[#FF6B35]/15 text-[10px] font-semibold text-[#FF6B35]\">\n 1\n </div>\n <p className=\"text-[12px] leading-snug text-neutral-400\">\n Comment on everything you want to fix\n </p>\n </div>\n <div className=\"flex items-start gap-2.5\">\n <div className=\"mt-0.5 flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-[#FF6B35]/15 text-[10px] font-semibold text-[#FF6B35]\">\n 2\n </div>\n <p className=\"text-[12px] leading-snug text-neutral-400\">Switch to your coding agent</p>\n </div>\n <div className=\"flex items-start gap-2.5\">\n <div className=\"mt-0.5 flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full bg-[#FF6B35]/15 text-[10px] font-semibold text-[#FF6B35]\">\n 3\n </div>\n <p className=\"text-[12px] leading-snug text-neutral-400\">\"Fix open comments\"</p>\n </div>\n </div>\n )\n}\n\nfunction AnnotationItem({\n annotation,\n number,\n isSelected,\n onSelect,\n onHover,\n onDelete,\n onUpdate\n}: {\n annotation: Annotation\n number: number\n isSelected: boolean\n onSelect: () => void\n onHover: (hovered: boolean) => void\n onDelete: () => void\n onUpdate: (patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => void\n}) {\n const [isEditing, setIsEditing] = useState(false)\n const [draft, setDraft] = useState(annotation.body)\n const editRef = useRef<HTMLTextAreaElement>(null)\n useEffect(() => {\n if (isEditing) editRef.current?.focus()\n }, [isEditing])\n const saveEdit = () => {\n const body = draft.trim()\n if (!body) return\n if (body !== annotation.body) onUpdate({ body })\n setIsEditing(false)\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={onSelect}\n onMouseEnter={() => onHover(true)}\n onMouseLeave={() => onHover(false)}\n onKeyDown={e => {\n if (e.target === e.currentTarget && (e.key === \"Enter\" || e.key === \" \")) onSelect()\n }}\n className={`group relative mb-0.5 cursor-pointer rounded-xl p-2.5 transition-all duration-150 ${\n isSelected ? \"bg-[#FF6B35]/10 ring-1 ring-[#FF6B35]/20\" : \"hover:bg-white/[0.04]\"\n }`}\n >\n <div className=\"absolute top-2 right-2 z-10 flex gap-0.5 rounded-full border border-neutral-700 bg-neutral-900/70 p-0.5 opacity-0 backdrop-blur-sm transition-opacity group-hover:opacity-100 group-focus-within:opacity-100\">\n <button\n type=\"button\"\n title=\"Edit comment\"\n aria-label=\"Edit comment\"\n onClick={e => {\n e.stopPropagation()\n setDraft(annotation.body)\n setIsEditing(true)\n }}\n className=\"rounded-full p-1 text-neutral-400 hover:bg-white/[0.08] hover:text-white\"\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </button>\n <button\n type=\"button\"\n title={annotation.status === \"open\" ? \"Resolve comment\" : \"Reopen comment\"}\n aria-label={annotation.status === \"open\" ? \"Resolve comment\" : \"Reopen comment\"}\n onClick={e => {\n e.stopPropagation()\n onHover(false)\n onUpdate({ status: annotation.status === \"open\" ? \"resolved\" : \"open\" })\n }}\n className=\"rounded-full p-1 text-neutral-400 hover:bg-white/[0.08] hover:text-white\"\n >\n {annotation.status === \"open\" ? (\n <Check className=\"h-3.5 w-3.5\" />\n ) : (\n <RotateCcw className=\"h-3.5 w-3.5\" />\n )}\n </button>\n <button\n type=\"button\"\n title=\"Delete comment\"\n aria-label=\"Delete comment\"\n onClick={e => {\n e.stopPropagation()\n onDelete()\n }}\n className=\"rounded-full p-1 text-neutral-400 hover:bg-white/[0.08] hover:text-white\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"flex items-start gap-2.5\">\n <div\n className={`mt-0.5 flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full text-[11px] font-semibold ${\n annotation.status === \"open\"\n ? \"bg-[#FF6B35] text-white\"\n : \"bg-neutral-700 text-neutral-400\"\n }`}\n >\n {number}\n </div>\n <div className=\"min-w-0 flex-1 pr-4\">\n {isEditing ? (\n <div>\n <textarea\n ref={editRef}\n value={draft}\n onClick={e => e.stopPropagation()}\n onChange={e => setDraft(e.target.value)}\n onKeyDown={e => {\n if (e.key === \"Escape\") setIsEditing(false)\n if ((e.metaKey || e.ctrlKey) && e.key === \"Enter\") saveEdit()\n }}\n className=\"w-full resize-y rounded border border-neutral-700 bg-neutral-900 p-2 text-[13px] text-white outline-none focus:border-[#FF6B35]\"\n rows={3}\n maxLength={4096}\n />\n <div className=\"mt-1 flex gap-2 text-xs\">\n <button\n type=\"button\"\n onClick={e => {\n e.stopPropagation()\n saveEdit()\n }}\n disabled={!draft.trim()}\n className=\"text-[#FF6B35] disabled:opacity-40\"\n >\n Save\n </button>\n <button\n type=\"button\"\n onClick={e => {\n e.stopPropagation()\n setIsEditing(false)\n }}\n className=\"text-neutral-400\"\n >\n Cancel\n </button>\n </div>\n </div>\n ) : (\n <p className=\"text-[13px] leading-relaxed text-neutral-200\">{annotation.body}</p>\n )}\n {annotation.target.contentNearPin && (\n <p className=\"mt-1 truncate text-[11px] text-neutral-600\">\n {annotation.target.contentNearPin}\n </p>\n )}\n {annotation.resolution && (\n <p className=\"mt-1.5 text-[11px] text-emerald-400/80 italic\">{annotation.resolution}</p>\n )}\n </div>\n </div>\n </div>\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport type { SlideConfig } from \"../types\"\nimport type { Annotation, AnnotationStorageAdapter, AnnotationTarget } from \"./types\"\n\nimport { createHttpAdapter } from \"./adapters/http\"\n\nexport function useAnnotations(\n slidesOrAdapter?: SlideConfig[] | AnnotationStorageAdapter,\n adapter?: AnnotationStorageAdapter\n) {\n const slides = Array.isArray(slidesOrAdapter) ? slidesOrAdapter : undefined\n const storage = Array.isArray(slidesOrAdapter) ? adapter : (slidesOrAdapter ?? adapter)\n const adapterRef = useRef(storage ?? createHttpAdapter())\n const slidesRef = useRef(slides)\n slidesRef.current = slides\n const [annotations, setAnnotations] = useState<Annotation[]>([])\n\n // Load on mount and subscribe to external updates\n useEffect(() => {\n adapterRef.current.load().then(loaded => {\n const configuredSlides = slidesRef.current\n const migrated = loaded.map(annotation => {\n if (annotation.slideId || !configuredSlides) return annotation\n const id = configuredSlides[annotation.slideIndex]?.id\n return id ? { ...annotation, slideId: id } : annotation\n })\n setAnnotations(migrated)\n if (migrated.some((annotation, index) => annotation !== loaded[index])) {\n void adapterRef.current.replaceAll?.(migrated)\n }\n })\n return adapterRef.current.subscribe?.(setAnnotations)\n }, [])\n\n const addAnnotation = useCallback(\n (\n slideIndex: number,\n slideTitle: string,\n target: AnnotationTarget,\n body: string,\n slideId?: string\n ) => {\n const annotation: Annotation = {\n id: crypto.randomUUID(),\n slideIndex,\n ...(slideId && { slideId }),\n slideTitle,\n target,\n body,\n createdAt: new Date().toISOString(),\n status: \"open\"\n }\n setAnnotations(prev => [...prev, annotation])\n adapterRef.current.add(annotation)\n },\n []\n )\n\n const deleteAnnotation = useCallback((id: string) => {\n setAnnotations(prev => prev.filter(a => a.id !== id))\n adapterRef.current.remove(id)\n }, [])\n\n const updateAnnotation = useCallback(\n (id: string, patch: Partial<Pick<Annotation, \"body\" | \"status\">>) => {\n const current = annotations.find(a => a.id === id)\n if (!current) return\n const updated = { body: patch.body ?? current.body, status: patch.status ?? current.status }\n setAnnotations(prev => prev.map(a => (a.id === id ? { ...a, ...updated } : a)))\n void adapterRef.current.update?.(id, updated)\n },\n [annotations]\n )\n\n const getSlideAnnotations = useCallback(\n (slideIndex: number) => annotations.filter(a => a.slideIndex === slideIndex),\n [annotations]\n )\n\n const openCount = useMemo(\n () => annotations.filter(a => a.status === \"open\").length,\n [annotations]\n )\n\n // Allow external state updates (e.g. from postMessage adapter)\n const updateAnnotations = useCallback((updated: Annotation[]) => {\n setAnnotations(updated)\n }, [])\n\n return {\n annotations,\n addAnnotation,\n deleteAnnotation,\n updateAnnotation,\n getSlideAnnotations,\n openCount,\n updateAnnotations\n }\n}\n","import type { Annotation, AnnotationsFile, AnnotationStorageAdapter } from \"../types\"\n\nconst ENDPOINT = \"/__promptslide_annotations\"\n\nasync function loadAll(): Promise<Annotation[]> {\n try {\n const res = await fetch(ENDPOINT)\n if (!res.ok) return []\n const data: AnnotationsFile = await res.json()\n return data.annotations || []\n } catch {\n return []\n }\n}\n\nasync function saveAll(annotations: Annotation[]): Promise<void> {\n const data: AnnotationsFile = { version: 1, annotations }\n await fetch(ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data)\n })\n}\n\n/** Storage adapter for local Vite dev server (reads/writes annotations.json via middleware) */\nexport function createHttpAdapter(): AnnotationStorageAdapter {\n let cache: Annotation[] = []\n\n return {\n async load() {\n cache = await loadAll()\n return cache\n },\n async add(annotation) {\n cache = [...cache, annotation]\n await saveAll(cache)\n },\n async remove(id) {\n cache = cache.filter(a => a.id !== id)\n await saveAll(cache)\n },\n async update(id, patch) {\n cache = cache.map(a => (a.id === id ? { ...a, ...patch } : a))\n await saveAll(cache)\n },\n async replaceAll(annotations) {\n cache = annotations\n await saveAll(cache)\n }\n }\n}\n","import type { ReactNode } from \"react\"\n\nimport { X } from \"lucide-react\"\nimport { useId } from \"react\"\n\nimport { cn } from \"./utils\"\n\nexport type InspectorMode = \"slide\" | \"editor\" | \"comments\"\n\n/** Core-owned docking and navigation; development tools portal into the editor slot. */\nexport function Inspector({\n mode,\n visible,\n editorAvailable,\n width,\n overlay,\n onSelect,\n onClose,\n slideSettings,\n comments\n}: {\n mode: InspectorMode | null\n visible: boolean\n editorAvailable: boolean\n width: number\n overlay: boolean\n onSelect: (mode: InspectorMode) => void\n onClose: () => void\n slideSettings: ReactNode\n comments: ReactNode\n}) {\n const prefix = useId()\n const tabs: { id: InspectorMode; label: string }[] = [\n { id: \"slide\", label: \"Slide\" },\n ...(editorAvailable ? [{ id: \"editor\" as const, label: \"Elements\" }] : []),\n { id: \"comments\", label: \"Comments\" }\n ]\n const closeLabel =\n mode === \"editor\"\n ? \"Done editing\"\n : mode === \"comments\"\n ? \"Hide comments\"\n : \"Close slide settings\"\n return (\n <aside\n data-ps-inspector\n aria-label=\"Inspector\"\n aria-hidden={!visible}\n inert={!visible}\n className={cn(\n \"h-full shrink-0 overflow-hidden bg-neutral-950 text-white transition-[width,transform] duration-200 ease-out motion-reduce:transition-none print:hidden\",\n overlay && \"fixed inset-y-0 right-0 z-[60]\",\n overlay && !visible && \"translate-x-full\"\n )}\n style={{ width: visible ? width : 0, maxWidth: overlay ? \"90vw\" : undefined }}\n onKeyDown={event => {\n // Native button activation must not also advance the presentation.\n if (\n (event.key === \" \" || event.key === \"Enter\") &&\n (event.target as HTMLElement).closest(\"button\")\n )\n event.stopPropagation()\n }}\n >\n <div className=\"flex h-full min-h-0 w-full flex-col border-l border-neutral-800\">\n <div\n data-ps-inspector-header\n className=\"flex shrink-0 items-center gap-1 border-b border-neutral-800 px-2 py-2\"\n >\n <div\n role=\"tablist\"\n aria-label=\"Inspector sections\"\n className=\"flex min-w-0 flex-1 gap-1\"\n onKeyDown={event => {\n if (![\"ArrowLeft\", \"ArrowRight\", \"Home\", \"End\"].includes(event.key)) return\n event.preventDefault()\n event.stopPropagation()\n const buttons = Array.from(\n event.currentTarget.querySelectorAll<HTMLButtonElement>(\"button\")\n )\n const index = buttons.indexOf(event.target as HTMLButtonElement)\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? buttons.length - 1\n : (index + (event.key === \"ArrowRight\" ? 1 : -1) + buttons.length) %\n buttons.length\n buttons[next]?.focus()\n }}\n >\n {tabs.map(tab => (\n <button\n key={tab.id}\n id={`${prefix}-tab-${tab.id}`}\n role=\"tab\"\n aria-selected={mode === tab.id}\n aria-controls={`${prefix}-panel-${tab.id}`}\n tabIndex={mode === tab.id ? 0 : -1}\n className={cn(\n \"rounded-md px-2 py-1.5 text-xs font-medium hover:bg-neutral-800 focus-visible:outline-2 focus-visible:outline-orange-500\",\n mode === tab.id ? \"bg-neutral-800 text-white\" : \"text-neutral-400\"\n )}\n onClick={() => onSelect(tab.id)}\n >\n {tab.label}\n </button>\n ))}\n </div>\n <button\n onClick={onClose}\n aria-label={closeLabel}\n title={closeLabel}\n className=\"shrink-0 rounded-md p-1.5 text-neutral-400 hover:bg-neutral-800 hover:text-white focus-visible:outline-2 focus-visible:outline-orange-500\"\n >\n <X size={16} />\n </button>\n </div>\n <div\n id={`${prefix}-panel-slide`}\n role=\"tabpanel\"\n aria-labelledby={`${prefix}-tab-slide`}\n hidden={mode !== \"slide\"}\n className=\"min-h-0 flex-1\"\n >\n {slideSettings}\n </div>\n <div\n id={`${prefix}-panel-editor`}\n role=\"tabpanel\"\n aria-labelledby={`${prefix}-tab-editor`}\n hidden={mode !== \"editor\"}\n className=\"min-h-0 flex-1\"\n >\n <div\n data-ps-editor-panel\n data-open={mode === \"editor\" && visible}\n aria-hidden={mode !== \"editor\" || !visible}\n inert={mode !== \"editor\" || !visible}\n className=\"h-full w-full\"\n />\n </div>\n <div\n id={`${prefix}-panel-comments`}\n role=\"tabpanel\"\n aria-labelledby={`${prefix}-tab-comments`}\n hidden={mode !== \"comments\"}\n className=\"min-h-0 flex-1\"\n >\n {comments}\n </div>\n </div>\n </aside>\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","export const DEFAULT_LOOP_CONFIG = { version: 1, defaultDuration: 5, slides: {} }\n\nexport function validateLoopConfig(value) {\n if (\n !value ||\n value.version !== 1 ||\n !validDuration(value.defaultDuration) ||\n !value.slides ||\n typeof value.slides !== \"object\" ||\n Array.isArray(value.slides)\n ) {\n throw new Error(\"Invalid loop settings\")\n }\n const slides = Object.create(null)\n if (Object.keys(value.slides).length > 1000) throw new Error(\"Too many slides\")\n for (const [id, item] of Object.entries(value.slides)) {\n if (\n !id ||\n id.length > 256 ||\n !item ||\n typeof item !== \"object\" ||\n (item.excluded !== undefined && typeof item.excluded !== \"boolean\") ||\n (item.steps !== undefined &&\n (!Number.isInteger(item.steps) || item.steps < 0 || item.steps > 1000)) ||\n (item.dwell !== undefined &&\n (!Array.isArray(item.dwell) ||\n item.dwell.length > 1001 ||\n !item.dwell.every(duration => duration === null || validDuration(duration))))\n )\n throw new Error(`Invalid timing for ${id}`)\n slides[id] = {\n ...(item.excluded !== undefined ? { excluded: item.excluded } : {}),\n ...(item.steps !== undefined ? { steps: item.steps } : {}),\n ...(item.dwell !== undefined ? { dwell: [...item.dwell] } : {})\n }\n }\n return { version: 1, defaultDuration: value.defaultDuration, slides }\n}\n\nexport function validDuration(value) {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0.1 && value <= 3600\n}\n\nexport function loopSlideKey(slide, index) {\n return slide.id || String(index + 1)\n}\n\nexport function stateDuration(config, slide, index, step) {\n return config.slides[loopSlideKey(slide, index)]?.dwell?.[step] ?? config.defaultDuration\n}\n\nexport function includedSlides(config, slides) {\n return slides.flatMap((slide, index) =>\n config.slides[loopSlideKey(slide, index)]?.excluded ? [] : [index]\n )\n}\n\nexport function loopDuration(config, slides) {\n return includedSlides(config, slides).reduce((total, index) => {\n const slide = slides[index]\n for (let step = 0; step <= slide.steps; step++)\n total += stateDuration(config, slide, index, step)\n return total\n }, 0)\n}\n","import { createContext, useContext, type ReactNode } from \"react\"\n\nimport type { LoopConfig } from \"../types\"\n\nimport { DEFAULT_LOOP_CONFIG } from \"./config.mjs\"\n\nconst LoopContext = createContext<LoopConfig>(DEFAULT_LOOP_CONFIG)\n\n/** The CLI supplies the deck's loop-config.json in development and production. */\nexport function LoopConfigProvider({\n config,\n children\n}: {\n config: LoopConfig\n children: ReactNode\n}) {\n return <LoopContext.Provider value={config}>{children}</LoopContext.Provider>\n}\n\nexport const useDefaultLoopConfig = () => useContext(LoopContext)\n","import { Check, Download, Play, RotateCcw } from \"lucide-react\"\nimport { useId, useState } from \"react\"\n\nimport type { LoopConfig, SlideConfig } from \"../types\"\n\nimport {\n includedSlides,\n loopDuration,\n loopSlideKey,\n stateDuration,\n validateLoopConfig\n} from \"./config.mjs\"\n\nconst button =\n \"rounded-md border border-neutral-700 px-2.5 py-2 text-xs hover:bg-neutral-800 disabled:opacity-40 focus-visible:outline-2 focus-visible:outline-orange-500\"\n\nfunction DurationInput({\n value,\n label,\n onCommit,\n onFocus,\n id\n}: {\n value: number\n label: string\n onCommit: (value: number) => void\n onFocus?: () => void\n id?: string\n}) {\n return (\n <span className=\"inline-flex w-20 shrink-0 items-center gap-1 rounded-md border border-neutral-700 bg-neutral-950 px-2.5 focus-within:border-orange-500 focus-within:outline-2 focus-within:outline-orange-500/30\">\n <input\n key={value}\n id={id}\n aria-label={label}\n className=\"min-w-0 w-full bg-transparent py-2 text-right text-sm tabular-nums text-white outline-none [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none\"\n style={{ colorScheme: \"dark\" }}\n type=\"number\"\n min=\"0.1\"\n max=\"3600\"\n step=\"0.1\"\n defaultValue={value}\n onFocus={onFocus}\n onBlur={event => {\n const next = event.target.valueAsNumber\n if (Number.isFinite(next) && next >= 0.1 && next <= 3600) {\n if (next !== value) onCommit(next)\n } else event.target.value = String(value)\n }}\n />\n <span aria-hidden=\"true\" className=\"text-xs text-neutral-500\">\n s\n </span>\n </span>\n )\n}\n\n/** Slide-specific settings follow the viewer's current slide and animation step. */\nexport function LoopSettings({\n slides,\n currentSlide,\n animationStep,\n config,\n onChange,\n onStepChange,\n onSave,\n onStart,\n onRevert,\n dirty\n}: {\n slides: SlideConfig[]\n currentSlide: number\n animationStep: number\n config: LoopConfig\n onChange: (config: LoopConfig) => void\n onStepChange: (step: number) => void\n onSave: (config: LoopConfig) => Promise<string>\n onStart: (config: LoopConfig) => void\n onRevert: () => void\n dirty: boolean\n}) {\n const defaultDurationId = useId()\n const [message, setMessage] = useState(\"\")\n const [saving, setSaving] = useState(false)\n const slide = slides[currentSlide]\n const key = slide ? loopSlideKey(slide, currentSlide) : \"\"\n const settings = config.slides[key]\n const changedSteps = settings?.steps !== undefined && settings.steps !== slide?.steps\n const updateDuration = (step: number, value: number | null) => {\n if (!slide) return\n const dwell = Array.from({ length: slide.steps + 1 }, (_, i) => settings?.dwell?.[i] ?? null)\n dwell[step] = value\n onChange({\n ...config,\n slides: { ...config.slides, [key]: { ...settings, steps: slide.steps, dwell } }\n })\n }\n const save = async () => {\n setSaving(true)\n try {\n setMessage(await onSave(validateLoopConfig(config)))\n } catch (error) {\n setMessage(error instanceof Error ? error.message : \"Could not save loop settings\")\n } finally {\n setSaving(false)\n }\n }\n const download = () => {\n const url = URL.createObjectURL(\n new Blob([JSON.stringify(config, null, 2) + \"\\n\"], { type: \"application/json\" })\n )\n const a = document.createElement(\"a\")\n a.href = url\n a.download = \"loop-config.json\"\n a.click()\n URL.revokeObjectURL(url)\n setMessage(\n \"Place loop-config.json in the project folder to include these settings in builds and publishing.\"\n )\n }\n return (\n <section\n aria-label=\"Slide settings\"\n className=\"flex h-full min-h-0 flex-col text-sm text-white\"\n >\n <div className=\"min-h-0 flex-1 overflow-y-auto p-4\">\n {slide && (\n <>\n <p className=\"text-[10px] font-semibold uppercase tracking-wider text-neutral-500\">\n Slide {currentSlide + 1}\n </p>\n <h2 className=\"mt-1 truncate text-base font-semibold\">\n {slide.title || slide.id || `Slide ${currentSlide + 1}`}\n </h2>\n <p className=\"mt-1 text-xs text-neutral-400\">\n Select slides in the thumbnail rail. Select a state below to preview it on the canvas.\n </p>\n <label className=\"mt-5 flex items-center justify-between gap-3 border-b border-neutral-800 pb-4\">\n Include in loop\n <span className=\"relative flex h-5 w-5 shrink-0 items-center justify-center\">\n <input\n aria-label=\"Include current slide in loop\"\n className=\"peer h-5 w-5 cursor-pointer appearance-none rounded border border-neutral-600 bg-neutral-950 transition-colors checked:border-orange-500 checked:bg-orange-500 hover:border-neutral-400 checked:hover:border-orange-400 checked:hover:bg-orange-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-orange-500\"\n type=\"checkbox\"\n checked={!settings?.excluded}\n onChange={event =>\n onChange({\n ...config,\n slides: {\n ...config.slides,\n [key]: { ...settings, excluded: !event.target.checked }\n }\n })\n }\n />\n <Check\n aria-hidden=\"true\"\n size={14}\n strokeWidth={3}\n className=\"pointer-events-none absolute text-white opacity-0 peer-checked:opacity-100\"\n />\n </span>\n </label>\n <h3 className=\"mb-2 mt-4 text-xs font-semibold text-neutral-300\">\n State timings <span className=\"font-normal text-neutral-500\">· seconds</span>\n </h3>\n {changedSteps && (\n <p role=\"status\" className=\"mb-3 text-xs text-amber-300\">\n This slide's step count changed. Review its timings; new states use the default.\n </p>\n )}\n <div className=\"space-y-1.5\" aria-label=\"Slide states\">\n {Array.from({ length: slide.steps + 1 }, (_, step) => {\n const label = step === 0 ? \"Initial view\" : `Step ${step}`\n const inherited = settings?.dwell?.[step] == null\n return (\n <div\n key={`${key}:${step}`}\n className={`flex items-center gap-1 rounded-md border p-1 ${animationStep === step ? \"border-orange-500/50 bg-orange-500/5\" : \"border-transparent\"}`}\n >\n <button\n aria-label={label}\n aria-pressed={animationStep === step}\n className=\"min-w-0 flex-1 rounded px-1 py-1.5 text-left text-xs hover:bg-neutral-800\"\n onClick={() => onStepChange(step)}\n >\n {label}\n <span className=\"mt-0.5 block text-[10px] text-neutral-500\">\n {inherited ? \"Default duration\" : \"Custom duration\"}\n </span>\n </button>\n <DurationInput\n value={stateDuration(config, slide, currentSlide, step)}\n label={`${label} duration in seconds`}\n onFocus={() => onStepChange(step)}\n onCommit={value => updateDuration(step, value)}\n />\n <button\n className=\"rounded p-1 text-neutral-500 hover:text-white disabled:opacity-30\"\n disabled={inherited}\n aria-label={`Use default for ${label.toLowerCase()}`}\n title=\"Use default duration\"\n onClick={() => updateDuration(step, null)}\n >\n <RotateCcw size={13} />\n </button>\n </div>\n )\n })}\n </div>\n <p className=\"mt-3 text-xs leading-relaxed text-neutral-500\">\n Durations include reveal animations. Allow enough time for videos and animations that\n play by themselves.\n </p>\n <button\n className={`${button} mt-3 w-full`}\n onClick={() => {\n const rest = { ...settings }\n delete rest.dwell\n delete rest.steps\n onChange({ ...config, slides: { ...config.slides, [key]: rest } })\n }}\n >\n Use default for this slide\n </button>\n </>\n )}\n <details className=\"mt-5 border-t border-neutral-800 pt-4\" open>\n <summary className=\"cursor-pointer text-xs font-semibold text-neutral-300\">\n Loop defaults\n </summary>\n <label\n htmlFor={defaultDurationId}\n className=\"mt-3 flex items-center justify-between gap-2 text-xs text-neutral-400\"\n >\n Seconds per state\n <DurationInput\n id={defaultDurationId}\n value={config.defaultDuration}\n label=\"Default duration in seconds\"\n onCommit={value => onChange({ ...config, defaultDuration: value })}\n />\n </label>\n <p className=\"mt-3 text-xs text-neutral-500\">\n {includedSlides(config, slides).length} slides ·{\" \"}\n {loopDuration(config, slides).toFixed(1)}s + slide transitions\n </p>\n </details>\n </div>\n <footer className=\"shrink-0 space-y-2 border-t border-neutral-800 p-3\">\n <p role=\"status\" className=\"text-xs text-neutral-400\">\n {dirty ? \"Unsaved loop settings\" : message || \"Loop settings saved\"}\n </p>\n <div className=\"flex gap-2\">\n <button\n className={`${button} flex-1`}\n disabled={!dirty || saving}\n onClick={() => {\n onRevert()\n setMessage(\"\")\n }}\n >\n Revert\n </button>\n <button\n className={`${button} flex-1 border-orange-500/50 text-orange-400`}\n disabled={saving}\n onClick={() => void save()}\n >\n {saving ? \"Saving…\" : \"Save settings\"}\n </button>\n </div>\n <div className=\"flex gap-2\">\n <button\n className={`${button} flex items-center justify-center gap-1.5`}\n aria-label=\"Download loop settings\"\n onClick={download}\n >\n <Download size={14} />\n </button>\n <button\n className={`${button} flex flex-1 items-center justify-center gap-1.5`}\n disabled={!includedSlides(config, slides).length || saving}\n onClick={() => onStart(validateLoopConfig(config))}\n >\n <Play size={14} /> Start loop\n </button>\n </div>\n </footer>\n </section>\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport type { LoopConfig, SlideConfig } from \"../types\"\n\nimport { includedSlides, stateDuration } from \"./config.mjs\"\n\ntype Options = {\n config: LoopConfig\n slides: SlideConfig[]\n currentSlide: number\n animationStep: number\n isTransitioning: boolean\n enabled: boolean\n advance: () => void\n goBack: () => void\n restartAtSlide: (index: number) => void\n}\n\nexport function useLoopPlayback({\n config,\n slides,\n currentSlide,\n animationStep,\n isTransitioning,\n enabled,\n advance,\n goBack,\n restartAtSlide\n}: Options) {\n const [paused, setPaused] = useState(false)\n const [hidden, setHidden] = useState(() => typeof document !== \"undefined\" && document.hidden)\n const [epoch, setEpoch] = useState(0)\n const [revision, setRevision] = useState(0)\n const remaining = useRef<number | undefined>(undefined)\n const identity = useRef(\"\")\n const included = useMemo(() => includedSlides(config, slides), [config, slides])\n\n useEffect(() => {\n const onVisibility = () => setHidden(document.hidden)\n document.addEventListener(\"visibilitychange\", onVisibility)\n return () => document.removeEventListener(\"visibilitychange\", onVisibility)\n }, [])\n\n const restart = useCallback(\n (index: number) => {\n setEpoch(value => value + 1)\n remaining.current = undefined\n restartAtSlide(index)\n },\n [restartAtSlide]\n )\n\n const resetTimer = useCallback(() => {\n remaining.current = undefined\n setRevision(value => value + 1)\n }, [])\n\n const move = (direction: 1 | -1) => {\n resetTimer()\n if (isTransitioning || included.length === 0) return\n if (direction === 1 && animationStep < (slides[currentSlide]?.steps ?? 0)) advance()\n else if (direction === -1 && animationStep > 0) goBack()\n else {\n const position = included.indexOf(currentSlide)\n restart(included[(position + direction + included.length) % included.length]!)\n }\n }\n\n useEffect(() => {\n if (!enabled) {\n remaining.current = undefined\n setPaused(false)\n return\n }\n const key = `${currentSlide}:${animationStep}:${epoch}:${revision}`\n if (identity.current !== key) {\n identity.current = key\n remaining.current = undefined\n }\n if (paused || hidden || isTransitioning || included.length === 0) return\n const slide = slides[currentSlide]\n if (!slide) return\n const duration =\n remaining.current ?? stateDuration(config, slide, currentSlide, animationStep) * 1000\n const deadline = performance.now() + duration\n const timer = window.setTimeout(() => {\n remaining.current = undefined\n if (animationStep < slide.steps) advance()\n else {\n const position = included.indexOf(currentSlide)\n restart(included[(position + 1) % included.length]!)\n }\n }, duration)\n return () => {\n window.clearTimeout(timer)\n remaining.current = Math.max(0, deadline - performance.now())\n }\n }, [\n enabled,\n paused,\n hidden,\n isTransitioning,\n currentSlide,\n animationStep,\n epoch,\n revision,\n config,\n slides,\n advance,\n restart,\n included\n ])\n\n return { paused, setPaused, epoch, restart, move }\n}\n","import type { ComponentPropsWithoutRef } from \"react\"\n\nimport { cn } from \"./utils\"\n\ntype ToolbarActionProps = Omit<\n ComponentPropsWithoutRef<\"button\">,\n \"aria-label\" | \"aria-pressed\" | \"className\"\n> & {\n label: string\n selected?: boolean\n}\n\n/** Shared icon action for both the viewer toolbar and the editor's toolbar portal. */\nexport function ToolbarAction({\n label,\n selected,\n title = label,\n children,\n ...props\n}: ToolbarActionProps) {\n return (\n <button\n {...props}\n type=\"button\"\n aria-label={label}\n aria-pressed={selected}\n title={title}\n className={cn(\n \"relative inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-transparent transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#FF6B35] disabled:cursor-default disabled:opacity-35 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0\",\n selected\n ? \"border-[#FF6B35]/50 bg-[#FF6B35]/15 text-[#FF6B35] enabled:hover:border-[#FF6B35] enabled:hover:bg-[#FF6B35]/25\"\n : \"text-neutral-400 enabled:hover:bg-neutral-800 enabled:hover:text-white\"\n )}\n >\n {children}\n </button>\n )\n}\n","import { Check, ChevronDown, Grid3X3, List, Monitor } from \"lucide-react\"\nimport { useEffect, useId, useLayoutEffect, useRef, useState } from \"react\"\n\nimport { cn } from \"./utils\"\n\nexport type ViewMode = \"slide\" | \"list\" | \"grid\"\n\nconst views = [\n { mode: \"slide\", label: \"Presentation view\", shortcut: \"V\", icon: Monitor },\n { mode: \"list\", label: \"List view\", shortcut: \"L\", icon: List },\n { mode: \"grid\", label: \"Grid view\", shortcut: \"G\", icon: Grid3X3 }\n] as const\n\nexport function ViewMenu({\n value,\n onChange,\n disabled\n}: {\n value: ViewMode\n onChange: (mode: ViewMode) => void\n disabled: boolean\n}) {\n const [open, setOpen] = useState(false)\n const id = useId()\n const root = useRef<HTMLDivElement>(null)\n const trigger = useRef<HTMLButtonElement>(null)\n const active = views.find(view => view.mode === value)!\n const Icon = active.icon\n\n useLayoutEffect(() => {\n if (open) root.current?.querySelector<HTMLElement>('[aria-checked=\"true\"]')?.focus()\n }, [open])\n useEffect(() => {\n if (!open) return\n const close = (event: PointerEvent) => {\n if (!root.current?.contains(event.target as Node)) setOpen(false)\n }\n document.addEventListener(\"pointerdown\", close)\n return () => document.removeEventListener(\"pointerdown\", close)\n }, [open])\n\n return (\n <div\n role=\"group\"\n aria-label=\"View selector\"\n ref={root}\n className=\"relative flex\"\n onBlur={event => {\n const next = event.relatedTarget\n if (next && !event.currentTarget.contains(next)) setOpen(false)\n }}\n onKeyDown={event => {\n // Toolbar navigation must not trigger slide advancement or deck shortcuts.\n event.stopPropagation()\n if (event.key === \"Escape\") {\n setOpen(false)\n trigger.current?.focus()\n } else if (open && event.key === \"Tab\") {\n trigger.current?.focus()\n setOpen(false)\n } else if ([\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key)) {\n event.preventDefault()\n if (!open) {\n setOpen(true)\n return\n }\n const items = Array.from(\n root.current!.querySelectorAll<HTMLButtonElement>('[role=\"menuitemradio\"]')\n )\n const index = items.indexOf(document.activeElement as HTMLButtonElement)\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? items.length - 1\n : (index + (event.key === \"ArrowDown\" ? 1 : -1) + items.length) % items.length\n items[next]?.focus()\n }\n }}\n >\n <button\n ref={trigger}\n disabled={disabled}\n aria-label=\"View options\"\n title={`View options · ${active.label}`}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? id : undefined}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md bg-neutral-800 px-2 text-white hover:bg-neutral-700 focus-visible:outline-2 focus-visible:outline-orange-500\"\n onClick={() => setOpen(previous => !previous)}\n >\n <Icon size={16} />\n <ChevronDown size={12} />\n </button>\n {open && (\n <div\n id={id}\n role=\"menu\"\n aria-label=\"View options\"\n className=\"absolute left-0 top-10 w-56 rounded-lg border border-neutral-700 bg-neutral-950 p-1 text-sm text-white\"\n >\n {views.map(({ mode, label, shortcut, icon: OptionIcon }) => (\n <button\n key={mode}\n role=\"menuitemradio\"\n aria-checked={mode === value}\n tabIndex={-1}\n className={cn(\n \"flex w-full items-center gap-2 rounded px-2 py-2 text-left text-neutral-300 hover:bg-neutral-800 focus:bg-neutral-800 focus:outline-none\",\n mode === value && \"text-white\"\n )}\n onClick={() => {\n onChange(mode)\n setOpen(false)\n trigger.current?.focus()\n }}\n >\n <OptionIcon size={16} />\n <span className=\"flex-1\">{label}</span>\n <span aria-hidden=\"true\" className=\"text-xs text-neutral-500\">\n {shortcut}\n </span>\n <Check size={14} className={mode === value ? \"text-orange-400\" : \"invisible\"} />\n </button>\n ))}\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","motion","jsx","motion","createContext","useContext","useMemo","jsx","motion","jsx","jsx","motion","useCallback","useEffect","useState","jsx","useState","useEffect","useCallback","ChevronDown","Download","Play","useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","useCallback","useEffect","useRef","useState","useEffect","useRef","useState","jsx","jsxs","jsx","jsxs","jsx","jsxs","useState","useRef","useCallback","useEffect","useEffect","useRef","useState","Fragment","jsx","jsxs","useCallback","useEffect","useMemo","useRef","useState","useRef","useState","useEffect","useCallback","useMemo","X","jsx","jsxs","X","createContext","useContext","jsx","createContext","useContext","Check","RotateCcw","useId","useState","Fragment","jsx","jsxs","useId","useState","Check","RotateCcw","useCallback","useEffect","useMemo","useRef","useState","useState","useRef","useMemo","useEffect","useCallback","jsx","Check","useEffect","useId","useRef","useState","jsx","jsxs","useState","useId","useRef","useEffect","Check","Fragment","jsx","jsxs","useRef","useLayoutEffect","useState","useEffect","useMemo","useCallback","Download","Play","ChevronDown"]}
|