{"version":3,"sources":["../src/core/path.ts","../src/core/createOrbit.ts","../src/react/CardOrbit.tsx","../src/react/CardOrbitMobile.tsx"],"names":["useState","useRef","useEffect","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["export const RISE = 280\nexport const ARC = (Math.PI / 2) * 90\nexport const EXIT = 240\nexport const PATH_LEN = RISE + ARC + EXIT\nexport const F = RISE / PATH_LEN\nexport const G = (RISE + ARC) / PATH_LEN\n\nexport const DEFAULT_ACTIVE_WINDOW = 0.72\nexport const DEFAULT_AUTO_SPEED = 45e-6\nexport const DEFAULT_DRAG_SENSITIVITY = 8e-4\nexport const DEFAULT_PERSPECTIVE = 3400\n\nexport type PathPoint = {\n  x: number\n  y: number\n  depth: number\n  fade: number\n  local: number\n  active: boolean\n}\n\nexport function samplePath(local: number, active: boolean): PathPoint {\n  const fade = active\n    ? Math.min(\n        Math.min(1, Math.max(0, local / 0.06)),\n        Math.min(1, Math.max(0, (1 - local) / 0.08)),\n      )\n    : 0\n\n  const depth = active\n    ? Math.sin(\n        (local < F ? local / (2 * F) : 0.5 + (local - F) / (2 * (1 - F))) * Math.PI,\n      )\n    : 0\n\n  let x: number\n  let y: number\n\n  if (local < F) {\n    x = -10\n    y = -300 + (local / F) * RISE\n  } else if (local < G) {\n    const ang = (180 + ((local - F) / (G - F)) * 90) * (Math.PI / 180)\n    x = 80 + 90 * Math.cos(ang)\n    y = -20 - 90 * Math.sin(ang)\n  } else {\n    x = 80 + ((local - G) / (1 - G)) * EXIT\n    y = 70\n  }\n\n  return { x, y, depth, fade, local, active }\n}\n\nexport function cardTransformStyle(point: PathPoint): {\n  zIndex: number\n  opacity: number\n  transform: string\n  pointerEvents: 'auto' | 'none'\n} {\n  const { x, y, depth, fade, local, active } = point\n\n  return {\n    zIndex: Math.round(20 + 80 * depth),\n    opacity: active ? fade * (0.4 + 0.6 * depth) : 0,\n    transform: [\n      `translate3d(calc(-50% + ${x}%), calc(-50% + ${y}%), ${-1000 + 1280 * depth}px)`,\n      `rotateX(${4 - 2 * depth}deg)`,\n      `rotateY(${-3 + 6 * local}deg)`,\n      'rotateZ(0deg)',\n      `scale(${0.44 + 0.74 * depth})`,\n    ].join(' '),\n    pointerEvents: depth > 0.72 ? 'auto' : 'none',\n  }\n}\n","import { DEFAULT_AUTO_SPEED, DEFAULT_DRAG_SENSITIVITY } from './path'\n\nexport type CreateOrbitOptions = {\n  autoSpeed?: number\n  dragSensitivity?: number\n  onProgress: (progress: number) => void\n}\n\nexport type OrbitController = {\n  attach(el: HTMLElement): void\n  detach(): void\n  setOptions(partial: {\n    autoSpeed?: number\n    dragSensitivity?: number\n  }): void\n  destroy(): void\n  getProgress(): number\n}\n\nexport function createOrbit(options: CreateOrbitOptions): OrbitController {\n  let autoSpeed = options.autoSpeed ?? DEFAULT_AUTO_SPEED\n  let dragSensitivity = options.dragSensitivity ?? DEFAULT_DRAG_SENSITIVITY\n  const onProgress = options.onProgress\n\n  let progress = 0\n  let dragging = false\n  let lastX: number | null = null\n  let lastY: number | null = null\n  let frame = 0\n  let last = 0\n  let el: HTMLElement | null = null\n  let running = false\n\n  const emit = () => onProgress(progress)\n\n  const onPointerDown = (e: PointerEvent) => {\n    lastX = e.clientX\n    lastY = e.clientY\n    dragging = true\n    el?.setPointerCapture(e.pointerId)\n  }\n\n  const onPointerMove = (e: PointerEvent) => {\n    if (!dragging || lastX === null || lastY === null) return\n    const dx = e.clientX - lastX\n    const dy = e.clientY - lastY\n    const delta = dy + 0.25 * dx\n    progress = (progress + dragSensitivity * delta + 1) % 1\n    emit()\n    lastX = e.clientX\n    lastY = e.clientY\n  }\n\n  const endDrag = (e: PointerEvent) => {\n    lastX = null\n    lastY = null\n    dragging = false\n    if (el?.hasPointerCapture?.(e.pointerId)) {\n      el.releasePointerCapture(e.pointerId)\n    }\n  }\n\n  const tick = (now: number) => {\n    const dt = now - last\n    last = now\n    if (!dragging) {\n      progress = (progress + autoSpeed * dt) % 1\n      emit()\n    }\n    frame = requestAnimationFrame(tick)\n  }\n\n  const startLoop = () => {\n    if (running) return\n    running = true\n    last = performance.now()\n    frame = requestAnimationFrame(tick)\n  }\n\n  const stopLoop = () => {\n    if (!running) return\n    running = false\n    cancelAnimationFrame(frame)\n    frame = 0\n  }\n\n  const detach = () => {\n    if (!el) return\n    el.removeEventListener('pointerdown', onPointerDown)\n    el.removeEventListener('pointermove', onPointerMove)\n    el.removeEventListener('pointerup', endDrag)\n    el.removeEventListener('pointercancel', endDrag)\n    el.removeEventListener('lostpointercapture', endDrag)\n    el = null\n  }\n\n  return {\n    attach(target) {\n      detach()\n      el = target\n      el.addEventListener('pointerdown', onPointerDown)\n      el.addEventListener('pointermove', onPointerMove)\n      el.addEventListener('pointerup', endDrag)\n      el.addEventListener('pointercancel', endDrag)\n      el.addEventListener('lostpointercapture', endDrag)\n      startLoop()\n    },\n    detach,\n    setOptions(partial) {\n      if (partial.autoSpeed !== undefined) autoSpeed = partial.autoSpeed\n      if (partial.dragSensitivity !== undefined) {\n        dragSensitivity = partial.dragSensitivity\n      }\n    },\n    destroy() {\n      stopLoop()\n      detach()\n      dragging = false\n      lastX = null\n      lastY = null\n    },\n    getProgress() {\n      return progress\n    },\n  }\n}\n","'use client'\n\nimport {\n  useEffect,\n  useRef,\n  useState,\n  type CSSProperties,\n} from 'react'\nimport { createOrbit } from '../core/createOrbit'\nimport {\n  DEFAULT_ACTIVE_WINDOW,\n  DEFAULT_AUTO_SPEED,\n  DEFAULT_DRAG_SENSITIVITY,\n  DEFAULT_PERSPECTIVE,\n  cardTransformStyle,\n  samplePath,\n} from '../core/path'\nimport '../core/styles.css'\n\nexport type CardOrbitProps = {\n  /** Image URLs to place on the path (order = phase offset). */\n  images: string[]\n  /** Optional alt text per image; falls back to `Card ${i + 1}`. */\n  alts?: string[]\n  className?: string\n  style?: CSSProperties\n  stageClassName?: string\n  cardClassName?: string\n  imageClassName?: string\n  /** Auto-advance rate when not dragging. Default `45e-6`. */\n  autoSpeed?: number\n  /** Pointer scrub sensitivity. Default `8e-4`. */\n  dragSensitivity?: number\n  /** Visible phase window in `(0, 1)`. Default `0.72`. */\n  activeWindow?: number\n  /** CSS perspective in px. Default `3400`. */\n  perspective?: number\n  ariaLabel?: string\n  /**\n   * Hide below `lg` (1024px) with built-in CSS.\n   * Pair with `CardOrbitMobile` for narrow screens. Default `true`.\n   */\n  desktopOnly?: boolean\n}\n\nexport function CardOrbit({\n  images,\n  alts,\n  className,\n  style,\n  stageClassName,\n  cardClassName,\n  imageClassName,\n  autoSpeed = DEFAULT_AUTO_SPEED,\n  dragSensitivity = DEFAULT_DRAG_SENSITIVITY,\n  activeWindow = DEFAULT_ACTIVE_WINDOW,\n  perspective = DEFAULT_PERSPECTIVE,\n  ariaLabel = 'Card orbit carousel',\n  desktopOnly = true,\n}: CardOrbitProps) {\n  const [progress, setProgress] = useState(0)\n  const rootRef = useRef<HTMLDivElement>(null)\n  const orbitRef = useRef<ReturnType<typeof createOrbit> | null>(null)\n\n  const hasImages = images.length > 0\n\n  useEffect(() => {\n    if (!hasImages) return\n    const node = rootRef.current\n    if (!node) return\n\n    const orbit = createOrbit({\n      onProgress: setProgress,\n    })\n    orbitRef.current = orbit\n    orbit.attach(node)\n    return () => {\n      orbit.destroy()\n      orbitRef.current = null\n    }\n  }, [hasImages])\n\n  useEffect(() => {\n    orbitRef.current?.setOptions({ autoSpeed, dragSensitivity })\n  }, [autoSpeed, dragSensitivity])\n\n  if (!hasImages) return null\n\n  const rootClass = [\n    'card-orbit',\n    desktopOnly ? 'card-orbit--desktop-only' : '',\n    className ?? '',\n  ]\n    .filter(Boolean)\n    .join(' ')\n\n  return (\n    <div\n      ref={rootRef}\n      className={rootClass}\n      style={{ perspective: `${perspective}px`, ...style }}\n      aria-label={ariaLabel}\n    >\n      <div\n        className={['card-orbit__stage', stageClassName].filter(Boolean).join(' ')}\n      >\n        {images.map((src, index) => {\n          const phase = (index / images.length + progress) % 1\n          const active = phase > 0 && phase < activeWindow\n          const local = active ? phase / activeWindow : 0\n          const point = samplePath(local, active)\n\n          return (\n            <figure\n              key={`${src}-${index}`}\n              className={['card-orbit__card', cardClassName].filter(Boolean).join(' ')}\n              style={cardTransformStyle(point)}\n            >\n              <img\n                src={src}\n                alt={alts?.[index] ?? `Card ${index + 1}`}\n                width={1200}\n                height={780}\n                className={['card-orbit__image', imageClassName].filter(Boolean).join(' ')}\n                draggable={false}\n                decoding=\"async\"\n              />\n            </figure>\n          )\n        })}\n      </div>\n    </div>\n  )\n}\n","'use client'\n\nimport type { CSSProperties } from 'react'\nimport '../core/styles.css'\n\nexport type CardOrbitMobileProps = {\n  images: string[]\n  alts?: string[]\n  className?: string\n  style?: CSSProperties\n  trackClassName?: string\n  cardClassName?: string\n  imageClassName?: string\n  /**\n   * Hide at `lg` and up (pair with desktop `CardOrbit`).\n   * Default `true`.\n   */\n  hideOnDesktop?: boolean\n  /** Marquee duration in seconds. Default `28`. */\n  durationSec?: number\n}\n\nexport function CardOrbitMobile({\n  images,\n  alts,\n  className,\n  style,\n  trackClassName,\n  cardClassName,\n  imageClassName,\n  hideOnDesktop = true,\n  durationSec = 28,\n}: CardOrbitMobileProps) {\n  if (images.length === 0) return null\n\n  const loop = [...images, ...images]\n\n  const rootClass = [\n    'card-orbit-mobile',\n    hideOnDesktop ? 'card-orbit-mobile--desktop-hide' : '',\n    className ?? '',\n  ]\n    .filter(Boolean)\n    .join(' ')\n\n  return (\n    <div className={rootClass} style={style}>\n      <div\n        className={['card-orbit-mobile__track', trackClassName].filter(Boolean).join(' ')}\n        style={{ animationDuration: `${durationSec}s` }}\n      >\n        {loop.map((src, i) => (\n          <figure\n            key={`${src}-${i}`}\n            className={['card-orbit-mobile__card', cardClassName].filter(Boolean).join(' ')}\n          >\n            <img\n              src={src}\n              alt={alts?.[i % images.length] ?? ''}\n              className={['card-orbit-mobile__image', imageClassName]\n                .filter(Boolean)\n                .join(' ')}\n              draggable={false}\n            />\n          </figure>\n        ))}\n      </div>\n    </div>\n  )\n}\n"]}