{"version":3,"sources":["../src/constants.ts","../src/utils/anonymous.ts","../src/api/client.ts","../src/components/GotchaProvider.tsx","../src/hooks/useSubmit.ts","../src/utils/cn.ts","../src/utils/device.ts","../src/components/GotchaButton.tsx","../src/components/Spinner.tsx","../src/components/modes/FeedbackMode.tsx","../src/components/modes/VoteMode.tsx","../src/components/modes/PollMode.tsx","../src/components/GotchaModal.tsx","../src/components/Gotcha.tsx","../src/hooks/useGotcha.ts"],"names":["API_BASE_URL","STORAGE_KEYS","DEFAULTS","RETRY_CONFIG","getAnonymousId","stored","id","DEFAULT_RETRY_CONFIG","fetchWithRetry","url","options","config","debug","lastError","attempt","response","error","delay","resolve","createApiClient","apiKey","baseUrl","headers","request","method","endpoint","body","idempotencyKey","data","payload","user","fullPayload","elementId","userId","GotchaContext","createContext","GotchaProvider","children","disabled","defaultUser","activeModalId","setActiveModalId","useState","client","useMemo","openModal","useCallback","closeModal","value","jsx","useGotchaContext","context","useContext","useSubmit","isLoading","setIsLoading","isCheckingExisting","setIsCheckingExisting","setError","existingResponse","setExistingResponse","useEffect","cancelled","existing","err","errorMessage","cn","classes","isTouchDevice","getResponsiveSize","size","isTouch","sizes","getInitialSystemTheme","GotchaButton","theme","customStyles","showOnHover","touchBehavior","onClick","isOpen","isParentHovered","setIsTouch","tapRevealed","setTapRevealed","systemTheme","setSystemTheme","darkQuery","handler","e","shouldShow","handleClick","buttonSize","isDark","baseStyles","GotchaIcon","FONT_ID","useCarterOneFont","link","Spinner","color","jsxs","FeedbackMode","placeholder","submitText","onSubmit","initialValues","isEditing","content","setContent","rating","setRating","handleSubmit","inputStyles","buttonStyles","StarRating","onChange","hovered","setHovered","starSize","buttonPadding","star","isFilled","VoteMode","initialVote","labels","activeVote","setActiveVote","previousVote","setPreviousVote","handleVote","vote","getButtonStyles","voteType","isSelected","iconSize","Fragment","ThumbsUpIcon","ThumbsDownIcon","PollMode","allowMultiple","initialSelected","selected","setSelected","handleToggle","option","prev","o","getOptionStyles","GotchaModal","mode","promptText","thankYouMessage","isSubmitted","voteLabels","onClose","anchorRect","modalRef","useRef","firstFocusableRef","isVisible","setIsVisible","isMobile","setIsMobile","timer","resolvedTheme","showAbove","modal","handleKeyDown","focusableElements","firstElement","lastElement","defaultPrompt","modalPadding","layeredShadow","modalStyles","Gotcha","experimentId","variant","showResults","position","visible","onOpen","onError","setIsSubmitted","setIsParentHovered","setAnchorRect","containerRef","container","parent","handleMouseEnter","handleMouseLeave","submit","handleOpen","handleClose","createPortal","useGotcha"],"mappings":"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","file":"index.mjs","sourcesContent":["// API URL\nexport const API_BASE_URL = 'https://gotcha.cx/api/v1';\n\n// Error codes\nexport const ERROR_CODES = {\n  INVALID_API_KEY: 'INVALID_API_KEY',\n  ORIGIN_NOT_ALLOWED: 'ORIGIN_NOT_ALLOWED',\n  RATE_LIMITED: 'RATE_LIMITED',\n  QUOTA_EXCEEDED: 'QUOTA_EXCEEDED',\n  INVALID_REQUEST: 'INVALID_REQUEST',\n  USER_NOT_FOUND: 'USER_NOT_FOUND',\n  INTERNAL_ERROR: 'INTERNAL_ERROR',\n} as const;\n\n// Local storage keys\nexport const STORAGE_KEYS = {\n  ANONYMOUS_ID: 'gotcha_anonymous_id',\n  OFFLINE_QUEUE: 'gotcha_offline_queue',\n} as const;\n\n// Default values\nexport const DEFAULTS = {\n  POSITION: 'top-right' as const,\n  SIZE: 'md' as const,\n  THEME: 'light' as const,\n  SHOW_ON_HOVER: true,\n  TOUCH_BEHAVIOR: 'always-visible' as const,\n  SUBMIT_TEXT: 'Submit',\n  THANK_YOU_MESSAGE: 'Thanks for your feedback!',\n} as const;\n\n// Size mappings (desktop/mobile in pixels)\nexport const SIZE_MAP = {\n  sm: { desktop: 24, mobile: 44 },\n  md: { desktop: 32, mobile: 44 },\n  lg: { desktop: 40, mobile: 48 },\n} as const;\n\n// Retry config\nexport const RETRY_CONFIG = {\n  MAX_RETRIES: 2,\n  BASE_DELAY_MS: 500,\n  MAX_DELAY_MS: 5000,\n} as const;\n","import { STORAGE_KEYS } from '../constants';\n\n/**\n * Get or create an anonymous user ID\n * Stored in localStorage for consistency across sessions\n */\nexport function getAnonymousId(): string {\n  if (typeof window === 'undefined') {\n    // SSR fallback - generate but don't persist\n    return `anon_${crypto.randomUUID()}`;\n  }\n\n  const stored = localStorage.getItem(STORAGE_KEYS.ANONYMOUS_ID);\n  if (stored) return stored;\n\n  const id = `anon_${crypto.randomUUID()}`;\n  localStorage.setItem(STORAGE_KEYS.ANONYMOUS_ID, id);\n  return id;\n}\n\n/**\n * Clear the anonymous ID (useful for testing)\n */\nexport function clearAnonymousId(): void {\n  if (typeof window !== 'undefined') {\n    localStorage.removeItem(STORAGE_KEYS.ANONYMOUS_ID);\n  }\n}\n","import { API_BASE_URL, RETRY_CONFIG } from '../constants';\nimport { SubmitResponsePayload, GotchaResponse, GotchaError, ExistingResponse, VoteType } from '../types';\nimport { getAnonymousId } from '../utils/anonymous';\n\ninterface ApiClientConfig {\n  apiKey: string;\n  baseUrl?: string;\n  debug?: boolean;\n}\n\ninterface RetryConfig {\n  maxRetries: number;\n  baseDelayMs: number;\n  maxDelayMs: number;\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n  maxRetries: RETRY_CONFIG.MAX_RETRIES,\n  baseDelayMs: RETRY_CONFIG.BASE_DELAY_MS,\n  maxDelayMs: RETRY_CONFIG.MAX_DELAY_MS,\n};\n\n/**\n * Fetch with automatic retry and exponential backoff\n */\nasync function fetchWithRetry(\n  url: string,\n  options: RequestInit,\n  config: RetryConfig = DEFAULT_RETRY_CONFIG,\n  debug: boolean = false\n): Promise<Response> {\n  let lastError: Error | null = null;\n\n  for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n    try {\n      if (debug && attempt > 0) {\n        console.log(`[Gotcha] Retry attempt ${attempt}/${config.maxRetries}`);\n      }\n\n      const response = await fetch(url, options);\n\n      // Don't retry client errors (4xx) except 429 (rate limit)\n      if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n        return response;\n      }\n\n      // Success - return immediately\n      if (response.ok) {\n        return response;\n      }\n\n      lastError = new Error(`HTTP ${response.status}`);\n    } catch (error) {\n      // Network error - retry\n      lastError = error as Error;\n      if (debug) {\n        console.log(`[Gotcha] Network error: ${lastError.message}`);\n      }\n    }\n\n    // Don't delay after last attempt\n    if (attempt < config.maxRetries) {\n      const delay = Math.min(\n        config.baseDelayMs * Math.pow(2, attempt),\n        config.maxDelayMs\n      );\n      await new Promise((resolve) => setTimeout(resolve, delay));\n    }\n  }\n\n  throw lastError;\n}\n\nexport function createApiClient(config: ApiClientConfig) {\n  const { apiKey, baseUrl = API_BASE_URL, debug = false } = config;\n\n  const headers = {\n    'Content-Type': 'application/json',\n    Authorization: `Bearer ${apiKey}`,\n  };\n\n  async function request<T>(\n    method: string,\n    endpoint: string,\n    body?: unknown\n  ): Promise<T> {\n    const url = `${baseUrl}${endpoint}`;\n    const idempotencyKey = crypto.randomUUID();\n\n    if (debug) {\n      console.log(`[Gotcha] ${method} ${endpoint}`, body);\n    }\n\n    const response = await fetchWithRetry(\n      url,\n      {\n        method,\n        headers: {\n          ...headers,\n          'Idempotency-Key': idempotencyKey,\n        },\n        body: body ? JSON.stringify(body) : undefined,\n      },\n      DEFAULT_RETRY_CONFIG,\n      debug\n    );\n\n    const data = await response.json();\n\n    if (!response.ok) {\n      const error = data.error as GotchaError;\n      if (debug) {\n        console.error(`[Gotcha] Error: ${error.code} - ${error.message}`);\n      }\n      throw error;\n    }\n\n    if (debug) {\n      console.log(`[Gotcha] Response:`, data);\n    }\n\n    return data as T;\n  }\n\n  return {\n    /**\n     * Submit a response (feedback, vote, etc.)\n     */\n    async submitResponse(\n      payload: Omit<SubmitResponsePayload, 'context'>\n    ): Promise<GotchaResponse> {\n      // Ensure user has an ID (anonymous if not provided)\n      const user = payload.user || {};\n      if (!user.id) {\n        user.id = getAnonymousId();\n      }\n\n      const fullPayload: SubmitResponsePayload = {\n        ...payload,\n        user,\n        context: {\n          url: typeof window !== 'undefined' ? window.location.href : undefined,\n          userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n        },\n      };\n\n      return request<GotchaResponse>('POST', '/responses', fullPayload);\n    },\n\n    /**\n     * Check if a user has an existing response for an element\n     */\n    async checkExistingResponse(\n      elementId: string,\n      userId: string\n    ): Promise<ExistingResponse | null> {\n      const url = `${baseUrl}/responses/check?elementId=${encodeURIComponent(elementId)}&userId=${encodeURIComponent(userId)}`;\n\n      if (debug) {\n        console.log(`[Gotcha] GET /responses/check`);\n      }\n\n      const response = await fetchWithRetry(\n        url,\n        {\n          method: 'GET',\n          headers,\n        },\n        DEFAULT_RETRY_CONFIG,\n        debug\n      );\n\n      const data = await response.json();\n\n      if (!response.ok) {\n        const error = data.error as GotchaError;\n        if (debug) {\n          console.error(`[Gotcha] Error: ${error.code} - ${error.message}`);\n        }\n        throw error;\n      }\n\n      if (data.exists) {\n        if (debug) {\n          console.log(`[Gotcha] Found existing response:`, data.response);\n        }\n        return data.response as ExistingResponse;\n      }\n\n      return null;\n    },\n\n    /**\n     * Update an existing response\n     */\n    async updateResponse(\n      id: string,\n      payload: {\n        content?: string;\n        title?: string;\n        rating?: number;\n        vote?: VoteType;\n        pollSelected?: string[];\n      },\n      userId?: string\n    ): Promise<GotchaResponse> {\n      const url = `${baseUrl}/responses/${id}${userId ? `?userId=${encodeURIComponent(userId)}` : ''}`;\n\n      if (debug) {\n        console.log(`[Gotcha] PATCH /responses/${id}`, payload);\n      }\n\n      const response = await fetchWithRetry(\n        url,\n        {\n          method: 'PATCH',\n          headers,\n          body: JSON.stringify(payload),\n        },\n        DEFAULT_RETRY_CONFIG,\n        debug\n      );\n\n      const data = await response.json();\n\n      if (!response.ok) {\n        const error = data.error as GotchaError;\n        if (debug) {\n          console.error(`[Gotcha] Error: ${error.code} - ${error.message}`);\n        }\n        throw error;\n      }\n\n      if (debug) {\n        console.log(`[Gotcha] Response updated:`, data);\n      }\n\n      return data as GotchaResponse;\n    },\n\n    /**\n     * Get the base URL (for debugging)\n     */\n    getBaseUrl(): string {\n      return baseUrl;\n    },\n  };\n}\n\nexport type ApiClient = ReturnType<typeof createApiClient>;\n","import React, { createContext, useContext, useMemo, useState, useCallback } from 'react';\nimport { createApiClient, ApiClient } from '../api/client';\nimport { GotchaUser } from '../types';\n\nexport interface GotchaProviderProps {\n  /** Your Gotcha API key */\n  apiKey: string;\n  /** React children */\n  children: React.ReactNode;\n  /** Override the API base URL (for testing/staging) */\n  baseUrl?: string;\n  /** Enable debug logging */\n  debug?: boolean;\n  /** Disable all Gotcha buttons globally */\n  disabled?: boolean;\n  /** Default user metadata applied to all submissions */\n  defaultUser?: GotchaUser;\n}\n\nexport interface GotchaContextValue {\n  client: ApiClient;\n  disabled: boolean;\n  defaultUser: GotchaUser;\n  debug: boolean;\n  // Modal management - only one open at a time\n  activeModalId: string | null;\n  openModal: (elementId: string) => void;\n  closeModal: () => void;\n}\n\nconst GotchaContext = createContext<GotchaContextValue | null>(null);\n\nexport function GotchaProvider({\n  apiKey,\n  children,\n  baseUrl,\n  debug = false,\n  disabled = false,\n  defaultUser = {},\n}: GotchaProviderProps) {\n  const [activeModalId, setActiveModalId] = useState<string | null>(null);\n\n  const client = useMemo(\n    () => createApiClient({ apiKey, baseUrl, debug }),\n    [apiKey, baseUrl, debug]\n  );\n\n  const openModal = useCallback((elementId: string) => {\n    setActiveModalId(elementId);\n  }, []);\n\n  const closeModal = useCallback(() => {\n    setActiveModalId(null);\n  }, []);\n\n  const value: GotchaContextValue = useMemo(\n    () => ({\n      client,\n      disabled,\n      defaultUser,\n      debug,\n      activeModalId,\n      openModal,\n      closeModal,\n    }),\n    [client, disabled, defaultUser, debug, activeModalId, openModal, closeModal]\n  );\n\n  return (\n    <GotchaContext.Provider value={value}>{children}</GotchaContext.Provider>\n  );\n}\n\nexport function useGotchaContext(): GotchaContextValue {\n  const context = useContext(GotchaContext);\n  if (!context) {\n    throw new Error('useGotchaContext must be used within a GotchaProvider');\n  }\n  return context;\n}\n","import { useState, useCallback, useEffect } from 'react';\nimport { useGotchaContext } from '../components/GotchaProvider';\nimport { ResponseMode, GotchaUser, GotchaResponse, VoteType, ExistingResponse } from '../types';\n\ninterface UseSubmitOptions {\n  elementId: string;\n  mode: ResponseMode;\n  experimentId?: string;\n  variant?: string;\n  pollOptions?: string[];\n  user?: GotchaUser;\n  onSuccess?: (response: GotchaResponse) => void;\n  onError?: (error: Error) => void;\n}\n\ninterface SubmitData {\n  content?: string;\n  title?: string;\n  rating?: number;\n  vote?: VoteType;\n  pollSelected?: string[];\n}\n\nexport function useSubmit(options: UseSubmitOptions) {\n  const { client, defaultUser } = useGotchaContext();\n  const [isLoading, setIsLoading] = useState(false);\n  const [isCheckingExisting, setIsCheckingExisting] = useState(false);\n  const [error, setError] = useState<string | null>(null);\n  const [existingResponse, setExistingResponse] = useState<ExistingResponse | null>(null);\n\n  // Check for existing response when user ID is provided\n  useEffect(() => {\n    const userId = options.user?.id || defaultUser?.id;\n    if (!userId) {\n      setExistingResponse(null);\n      return;\n    }\n\n    let cancelled = false;\n\n    const checkExisting = async () => {\n      setIsCheckingExisting(true);\n      try {\n        const existing = await client.checkExistingResponse(options.elementId, userId);\n        if (!cancelled) {\n          setExistingResponse(existing);\n        }\n      } catch {\n        // Ignore errors - just means no existing response found\n        if (!cancelled) {\n          setExistingResponse(null);\n        }\n      } finally {\n        if (!cancelled) {\n          setIsCheckingExisting(false);\n        }\n      }\n    };\n\n    checkExisting();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [client, options.elementId, options.user?.id, defaultUser?.id]);\n\n  const submit = useCallback(\n    async (data: SubmitData) => {\n      setIsLoading(true);\n      setError(null);\n\n      try {\n        const userId = options.user?.id || defaultUser?.id;\n        let response: GotchaResponse;\n\n        // If we have an existing response and a user ID, update instead of create\n        if (existingResponse && userId) {\n          response = await client.updateResponse(\n            existingResponse.id,\n            {\n              content: data.content,\n              title: data.title,\n              rating: data.rating,\n              vote: data.vote,\n              pollSelected: data.pollSelected,\n            },\n            userId\n          );\n        } else {\n          response = await client.submitResponse({\n            elementId: options.elementId,\n            mode: options.mode,\n            content: data.content,\n            title: data.title,\n            rating: data.rating,\n            vote: data.vote,\n            pollOptions: options.pollOptions,\n            pollSelected: data.pollSelected,\n            experimentId: options.experimentId,\n            variant: options.variant,\n            user: { ...defaultUser, ...options.user },\n          });\n        }\n\n        options.onSuccess?.(response);\n        return response;\n      } catch (err) {\n        const errorMessage = err instanceof Error ? err.message : 'Something went wrong';\n        setError(errorMessage);\n        options.onError?.(err instanceof Error ? err : new Error(errorMessage));\n        throw err;\n      } finally {\n        setIsLoading(false);\n      }\n    },\n    [client, defaultUser, options, existingResponse]\n  );\n\n  return {\n    submit,\n    isLoading,\n    isCheckingExisting,\n    error,\n    existingResponse,\n    isEditing: !!existingResponse,\n    clearError: () => setError(null),\n  };\n}\n","/**\n * Simple class name utility\n * Combines class names, filtering out falsy values\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n  return classes.filter(Boolean).join(' ');\n}\n","/**\n * Detect if the device supports touch\n */\nexport const isTouchDevice = (): boolean => {\n  if (typeof window === 'undefined') return false;\n  return 'ontouchstart' in window || navigator.maxTouchPoints > 0;\n};\n\n/**\n * Get the appropriate size based on device type\n */\nexport const getResponsiveSize = (\n  size: 'sm' | 'md' | 'lg',\n  isTouch: boolean\n): number => {\n  const sizes = {\n    sm: { desktop: 24, mobile: 32 },\n    md: { desktop: 32, mobile: 36 },\n    lg: { desktop: 40, mobile: 40 },\n  };\n\n  return isTouch ? sizes[size].mobile : sizes[size].desktop;\n};\n","import React, { useState, useEffect } from 'react';\nimport { Size, Theme, GotchaStyles } from '../types';\nimport { cn } from '../utils/cn';\nimport { isTouchDevice, getResponsiveSize } from '../utils/device';\n\nexport interface GotchaButtonProps {\n  size: Size;\n  theme: Theme;\n  customStyles?: GotchaStyles;\n  showOnHover: boolean;\n  touchBehavior: 'always-visible' | 'tap-to-reveal';\n  onClick: () => void;\n  isOpen: boolean;\n  isParentHovered?: boolean;\n}\n\n/**\n * Detect system color-scheme preference synchronously where possible,\n * falling back to 'light'. This avoids the flash that occurred when\n * the old code always initialised state as 'light' and corrected it\n * inside useEffect.\n */\nfunction getInitialSystemTheme(): 'light' | 'dark' {\n  if (typeof window === 'undefined') return 'light';\n  return window.matchMedia('(prefers-color-scheme: dark)').matches\n    ? 'dark'\n    : 'light';\n}\n\nexport function GotchaButton({\n  size,\n  theme,\n  customStyles,\n  showOnHover,\n  touchBehavior,\n  onClick,\n  isOpen,\n  isParentHovered = false,\n}: GotchaButtonProps) {\n  const [isTouch, setIsTouch] = useState(false);\n  const [tapRevealed, setTapRevealed] = useState(false);\n  const [systemTheme, setSystemTheme] = useState<'light' | 'dark'>(getInitialSystemTheme);\n\n  useEffect(() => {\n    setIsTouch(isTouchDevice());\n\n    // Keep systemTheme in sync when user changes OS preference\n    const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');\n    const handler = (e: MediaQueryListEvent) =>\n      setSystemTheme(e.matches ? 'dark' : 'light');\n    darkQuery.addEventListener('change', handler);\n    return () => darkQuery.removeEventListener('change', handler);\n  }, []);\n\n  // Determine visibility\n  const shouldShow = (() => {\n    if (isOpen) return true;\n    if (!isTouch && showOnHover) return isParentHovered;\n    if (isTouch && touchBehavior === 'tap-to-reveal') return tapRevealed;\n    return true;\n  })();\n\n  const handleClick = () => {\n    if (isTouch && touchBehavior === 'tap-to-reveal' && !tapRevealed) {\n      setTapRevealed(true);\n      return;\n    }\n    onClick();\n  };\n\n  const buttonSize = getResponsiveSize(size, isTouch);\n\n  // ── Resolve theme ────────────────────────────────────────────────\n  // \"auto\" must produce the *exact* same styles as the explicit theme\n  // it resolves to. Previously the initial state defaulted to 'light'\n  // regardless of the actual preference, causing a mismatch on the\n  // first render when the system was dark.\n  const resolvedTheme = theme === 'auto' ? systemTheme : theme;\n  const isDark = resolvedTheme === 'dark';\n\n  // ── Glass-bubble styles ──────────────────────────────────────────\n  // Simulates a raised glass dome / marble sitting on the surface:\n  //   - Bright borderTop highlight mimics light hitting the top edge\n  //   - Subtle darker base border grounds the bottom\n  //   - Vertical gradient: bright at top, more opaque at bottom\n  //   - Inset top shadow for inner refraction glow\n  //   - Inset bottom shadow for depth within the dome\n  //   - Outer shadow to anchor the bubble to the surface\n  const baseStyles: React.CSSProperties = {\n    width: buttonSize,\n    height: buttonSize,\n    borderRadius: '50%',\n    border: isDark\n      ? '1px solid rgba(255,255,255,0.15)'\n      : 'none',\n    cursor: 'pointer',\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n    background: isDark\n      ? 'linear-gradient(180deg, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.04) 60%, rgba(0,0,0,0.05) 100%)'\n      : 'linear-gradient(160deg, rgba(255,255,255,0.7) 0%, rgba(200,210,230,0.4) 40%, rgba(180,192,220,0.5) 100%)',\n    backdropFilter: 'blur(16px) saturate(170%)',\n    WebkitBackdropFilter: 'blur(16px) saturate(170%)',\n    color: isDark ? 'rgba(255,255,255,0.88)' : 'rgba(0,0,0,0.75)',\n    boxShadow: isDark\n      ? '0 4px 14px rgba(0,0,0,0.45), 0 1px 3px rgba(0,0,0,0.35)'\n      : '0 3px 12px rgba(0,0,0,0.12), 0 0 1px rgba(0,0,0,0.2)',\n    transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\n    opacity: shouldShow ? 1 : 0,\n    transform: shouldShow ? 'scale(1)' : 'scale(0.6)',\n    pointerEvents: shouldShow ? 'auto' : 'none',\n    ...customStyles?.button,\n  };\n\n  return (\n    <button\n      type=\"button\"\n      onClick={handleClick}\n      style={baseStyles}\n      className={cn('gotcha-button', isOpen && 'gotcha-button--open')}\n      aria-label=\"Give feedback on this feature\"\n      aria-expanded={isOpen}\n      aria-haspopup=\"dialog\"\n    >\n      <GotchaIcon size={buttonSize * 0.65} />\n    </button>\n  );\n}\n\nconst FONT_ID = 'gotcha-carter-one';\n\nfunction useCarterOneFont() {\n  useEffect(() => {\n    if (document.getElementById(FONT_ID)) return;\n    const link = document.createElement('link');\n    link.id = FONT_ID;\n    link.rel = 'stylesheet';\n    link.href = 'https://fonts.googleapis.com/css2?family=Carter+One&display=swap';\n    document.head.appendChild(link);\n  }, []);\n}\n\nfunction GotchaIcon({ size }: { size: number }) {\n  useCarterOneFont();\n  return (\n    <span\n      aria-hidden=\"true\"\n      style={{\n        fontFamily: \"'Carter One', cursive\",\n        fontSize: size,\n        lineHeight: 1,\n        display: 'flex',\n        alignItems: 'center',\n        justifyContent: 'center',\n        marginTop: size * 0.05,\n        marginRight: size * 0.05,\n        userSelect: 'none',\n      }}\n    >\n      G\n    </span>\n  );\n}\n","import React from 'react';\n\ninterface SpinnerProps {\n  size?: number;\n  color?: string;\n}\n\nexport function Spinner({ size = 16, color = 'currentColor' }: SpinnerProps) {\n  return (\n    <svg\n      width={size}\n      height={size}\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      style={{\n        animation: 'gotcha-spin 0.8s linear infinite',\n      }}\n    >\n      <style>\n        {`\n          @keyframes gotcha-spin {\n            from { transform: rotate(0deg); }\n            to { transform: rotate(360deg); }\n          }\n          @keyframes gotcha-dash {\n            0% { stroke-dasharray: 1, 62; stroke-dashoffset: 0; }\n            50% { stroke-dasharray: 40, 62; stroke-dashoffset: -12; }\n            100% { stroke-dasharray: 1, 62; stroke-dashoffset: -62; }\n          }\n        `}\n      </style>\n      <circle\n        cx=\"12\"\n        cy=\"12\"\n        r=\"10\"\n        stroke={color}\n        strokeWidth=\"2\"\n        strokeOpacity=\"0.12\"\n      />\n      <circle\n        cx=\"12\"\n        cy=\"12\"\n        r=\"10\"\n        stroke={color}\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        style={{\n          animation: 'gotcha-dash 1.2s ease-in-out infinite',\n        }}\n      />\n    </svg>\n  );\n}\n","import React, { useState, useEffect } from 'react';\nimport { GotchaStyles } from '../../types';\nimport { isTouchDevice } from '../../utils/device';\nimport { Spinner } from '../Spinner';\n\ninterface FeedbackModeProps {\n  theme: 'light' | 'dark' | 'custom';\n  placeholder?: string;\n  submitText: string;\n  isLoading: boolean;\n  onSubmit: (data: { content?: string; rating?: number }) => void;\n  customStyles?: GotchaStyles;\n  initialValues?: {\n    content?: string | null;\n    rating?: number | null;\n  };\n  isEditing?: boolean;\n}\n\nexport function FeedbackMode({\n  theme,\n  placeholder,\n  submitText,\n  isLoading,\n  onSubmit,\n  customStyles,\n  initialValues,\n  isEditing = false,\n}: FeedbackModeProps) {\n  const [content, setContent] = useState(initialValues?.content || '');\n  const [rating, setRating] = useState<number | null>(initialValues?.rating ?? null);\n  const [isTouch, setIsTouch] = useState(false);\n\n  useEffect(() => {\n    setIsTouch(isTouchDevice());\n  }, []);\n\n  // Update local state when initialValues change (e.g., after loading existing response)\n  useEffect(() => {\n    if (initialValues?.content !== undefined) {\n      setContent(initialValues.content || '');\n    }\n    if (initialValues?.rating !== undefined) {\n      setRating(initialValues.rating ?? null);\n    }\n  }, [initialValues?.content, initialValues?.rating]);\n\n  const isDark = theme === 'dark';\n\n  const handleSubmit = (e: React.FormEvent) => {\n    e.preventDefault();\n    if (!content.trim() && rating === null) return;\n    onSubmit({ content: content.trim() || undefined, rating: rating ?? undefined });\n  };\n\n  const inputStyles: React.CSSProperties = {\n    width: '100%',\n    padding: isTouch ? '12px 14px' : '10px 12px',\n    border: `1px solid ${isDark ? 'rgba(255,255,255,0.08)' : '#e2e8f0'}`,\n    borderRadius: 8,\n    backgroundColor: isDark ? 'rgba(55,65,81,0.5)' : '#fafbfc',\n    color: isDark ? '#f9fafb' : '#111827',\n    fontSize: isTouch ? 16 : 14, // 16px prevents iOS zoom on focus\n    resize: 'vertical',\n    minHeight: isTouch ? 100 : 80,\n    fontFamily: 'inherit',\n    outline: 'none',\n    transition: 'border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\n    lineHeight: 1.5,\n    ...customStyles?.input,\n  };\n\n  const buttonStyles: React.CSSProperties = {\n    width: '100%',\n    padding: isTouch ? '14px 16px' : '10px 16px',\n    border: 'none',\n    borderRadius: 8,\n    backgroundColor: isDark ? '#e2e8f0' : '#1e293b',\n    color: isDark ? '#1e293b' : '#ffffff',\n    fontSize: isTouch ? 16 : 14,\n    fontWeight: 500,\n    cursor: isLoading ? 'not-allowed' : 'pointer',\n    transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\n    letterSpacing: '0.01em',\n    ...customStyles?.submitButton,\n  };\n\n  return (\n    <form onSubmit={handleSubmit}>\n      {/* Rating (optional) */}\n      <div style={{ marginBottom: isTouch ? 16 : 12 }}>\n        <StarRating value={rating} onChange={setRating} isDark={isDark} isTouch={isTouch} />\n      </div>\n\n      {/* Text input */}\n      <textarea\n        value={content}\n        onChange={(e) => setContent(e.target.value)}\n        placeholder={placeholder || 'Share your thoughts...'}\n        style={inputStyles}\n        disabled={isLoading}\n        aria-label=\"Your feedback\"\n        onFocus={(e) => {\n          e.currentTarget.style.borderColor = '#1e293b';\n          e.currentTarget.style.boxShadow = '0 0 0 2px rgba(30,41,59,0.15)';\n          e.currentTarget.style.backgroundColor = isDark ? 'rgba(55,65,81,0.7)' : '#ffffff';\n        }}\n        onBlur={(e) => {\n          e.currentTarget.style.borderColor = isDark ? 'rgba(255,255,255,0.08)' : '#e2e8f0';\n          e.currentTarget.style.boxShadow = 'none';\n          e.currentTarget.style.backgroundColor = isDark ? 'rgba(55,65,81,0.5)' : '#fafbfc';\n        }}\n      />\n\n      {/* Submit button */}\n      <button\n        type=\"submit\"\n        disabled={isLoading || (!content.trim() && rating === null)}\n        style={{\n          ...buttonStyles,\n          marginTop: 12,\n          opacity: isLoading ? 0.8 : 1,\n          backgroundColor: (!content.trim() && rating === null)\n            ? (isDark ? '#374151' : '#e2e8f0')\n            : (isDark ? '#e2e8f0' : '#1e293b'),\n          color: (!content.trim() && rating === null)\n            ? (isDark ? '#6b7280' : '#94a3b8')\n            : (isDark ? '#1e293b' : '#ffffff'),\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'center',\n          gap: 8,\n        }}\n        onMouseEnter={(e) => {\n          if (!e.currentTarget.disabled) {\n            e.currentTarget.style.backgroundColor = isDark ? '#cbd5e1' : '#334155';\n          }\n        }}\n        onMouseLeave={(e) => {\n          if (!e.currentTarget.disabled) {\n            e.currentTarget.style.backgroundColor = isDark ? '#e2e8f0' : '#1e293b';\n          }\n        }}\n      >\n        {isLoading && <Spinner size={isTouch ? 18 : 16} color={isDark ? '#1e293b' : '#ffffff'} />}\n        {isLoading ? (isEditing ? 'Updating...' : 'Submitting...') : (isEditing ? 'Update' : submitText)}\n      </button>\n    </form>\n  );\n}\n\ninterface StarRatingProps {\n  value: number | null;\n  onChange: (rating: number) => void;\n  isDark: boolean;\n  isTouch: boolean;\n}\n\nfunction StarRating({ value, onChange, isDark, isTouch }: StarRatingProps) {\n  const [hovered, setHovered] = useState<number | null>(null);\n  const starSize = isTouch ? 28 : 18;\n  const buttonPadding = isTouch ? 6 : 3;\n\n  return (\n    <div\n      style={{\n        display: 'flex',\n        gap: isTouch ? 6 : 2,\n      }}\n      role=\"group\"\n      aria-label=\"Rating\"\n    >\n      {[1, 2, 3, 4, 5].map((star) => {\n        const isFilled = (hovered ?? value ?? 0) >= star;\n        return (\n          <button\n            key={star}\n            type=\"button\"\n            onClick={() => onChange(star)}\n            onMouseEnter={() => setHovered(star)}\n            onMouseLeave={() => setHovered(null)}\n            aria-label={`Rate ${star} out of 5`}\n            aria-pressed={value === star}\n            style={{\n              background: 'none',\n              border: 'none',\n              cursor: 'pointer',\n              padding: buttonPadding,\n              color: isFilled ? '#f59e0b' : (isDark ? 'rgba(255,255,255,0.12)' : '#e2e8f0'),\n              transition: 'color 0.15s cubic-bezier(0.4, 0, 0.2, 1), transform 0.15s cubic-bezier(0.4, 0, 0.2, 1)',\n              transform: (hovered !== null && hovered >= star) ? 'scale(1.1)' : 'scale(1)',\n            }}\n          >\n            <svg width={starSize} height={starSize} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n              <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n            </svg>\n          </button>\n        );\n      })}\n    </div>\n  );\n}\n","import React, { useEffect, useState } from 'react';\nimport { isTouchDevice } from '../../utils/device';\nimport { Spinner } from '../Spinner';\n\ninterface VoteModeProps {\n  theme: 'light' | 'dark' | 'custom';\n  isLoading: boolean;\n  onSubmit: (data: { vote: 'up' | 'down' }) => void;\n  initialVote?: 'up' | 'down' | null;\n  isEditing?: boolean;\n  labels?: { up: string; down: string };\n}\n\nexport function VoteMode({ theme, isLoading, onSubmit, initialVote, isEditing = false, labels }: VoteModeProps) {\n  const [isTouch, setIsTouch] = useState(false);\n  const [activeVote, setActiveVote] = useState<'up' | 'down' | null>(initialVote || null);\n  const [previousVote, setPreviousVote] = useState<'up' | 'down' | null>(initialVote || null);\n\n  useEffect(() => {\n    setIsTouch(isTouchDevice());\n  }, []);\n\n  // Update when initialVote changes (e.g., after loading existing response)\n  useEffect(() => {\n    if (initialVote !== undefined) {\n      setPreviousVote(initialVote);\n      setActiveVote(initialVote);\n    }\n  }, [initialVote]);\n\n  // Reset active vote when loading completes (but keep previous vote for edit mode)\n  useEffect(() => {\n    if (!isLoading && !isEditing) {\n      setActiveVote(null);\n    }\n  }, [isLoading, isEditing]);\n\n  const handleVote = (vote: 'up' | 'down') => {\n    setActiveVote(vote);\n    onSubmit({ vote });\n  };\n\n  const isDark = theme === 'dark';\n\n  const getButtonStyles = (voteType: 'up' | 'down'): React.CSSProperties => {\n    const isSelected = previousVote === voteType;\n    const selectedColor = voteType === 'up' ? '#10b981' : '#ef4444';\n    return {\n      flex: 1,\n      minWidth: 0,\n      overflow: 'hidden' as const,\n      padding: isTouch ? '14px 18px' : '10px 14px',\n      border: `1px solid ${isSelected\n        ? (voteType === 'up'\n          ? (isDark ? 'rgba(16,185,129,0.3)' : 'rgba(16,185,129,0.25)')\n          : (isDark ? 'rgba(239,68,68,0.3)' : 'rgba(239,68,68,0.25)'))\n        : (isDark ? 'rgba(255,255,255,0.08)' : '#e2e8f0')}`,\n      borderRadius: isTouch ? 10 : 8,\n      backgroundColor: isSelected\n        ? (voteType === 'up'\n          ? (isDark ? 'rgba(16,185,129,0.08)' : 'rgba(16,185,129,0.06)')\n          : (isDark ? 'rgba(239,68,68,0.08)' : 'rgba(239,68,68,0.06)'))\n        : (isDark ? 'rgba(55,65,81,0.5)' : '#fafbfc'),\n      color: isSelected\n        ? selectedColor\n        : (isDark ? '#d1d5db' : '#64748b'),\n      fontSize: isTouch ? 28 : 24,\n      cursor: isLoading ? 'not-allowed' : 'pointer',\n      transition: 'background-color 0.2s, border-color 0.2s, color 0.2s, transform 0.2s, box-shadow 0.2s',\n      display: 'flex',\n      alignItems: 'center',\n      justifyContent: 'center',\n      gap: isTouch ? 10 : 8,\n    };\n  };\n\n  const iconSize = isTouch ? 24 : 20;\n\n  return (\n    <div\n      style={{\n        display: 'flex',\n        gap: isTouch ? 12 : 10,\n      }}\n      role=\"group\"\n      aria-label=\"Vote\"\n    >\n      <button\n        type=\"button\"\n        onClick={() => handleVote('up')}\n        disabled={isLoading}\n        style={getButtonStyles('up')}\n        aria-label=\"Vote up - I like this\"\n        aria-pressed={previousVote === 'up'}\n        onMouseEnter={(e) => {\n          if (!isLoading) {\n            e.currentTarget.style.transform = 'translateY(-1px)';\n            e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.06)';\n          }\n        }}\n        onMouseLeave={(e) => {\n          e.currentTarget.style.transform = 'translateY(0)';\n          e.currentTarget.style.boxShadow = 'none';\n        }}\n      >\n        {isLoading && activeVote === 'up' ? (\n          <>\n            <Spinner size={iconSize} color={isDark ? '#f9fafb' : '#111827'} />\n            <span style={{ fontSize: isTouch ? 15 : 13, fontWeight: 500, letterSpacing: '0.01em' }}>\n              {isEditing ? 'Updating...' : 'Sending...'}\n            </span>\n          </>\n        ) : (\n          <>\n            <ThumbsUpIcon size={iconSize} />\n            <span style={{ fontSize: isTouch ? 15 : 13, fontWeight: 500, letterSpacing: '0.01em' }}>\n              {labels?.up || (previousVote === 'up' ? 'Liked' : 'Like')}\n            </span>\n          </>\n        )}\n      </button>\n\n      <button\n        type=\"button\"\n        onClick={() => handleVote('down')}\n        disabled={isLoading}\n        style={getButtonStyles('down')}\n        aria-label=\"Vote down - I don't like this\"\n        aria-pressed={previousVote === 'down'}\n        onMouseEnter={(e) => {\n          if (!isLoading) {\n            e.currentTarget.style.transform = 'translateY(-1px)';\n            e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.06)';\n          }\n        }}\n        onMouseLeave={(e) => {\n          e.currentTarget.style.transform = 'translateY(0)';\n          e.currentTarget.style.boxShadow = 'none';\n        }}\n      >\n        {isLoading && activeVote === 'down' ? (\n          <>\n            <Spinner size={iconSize} color={isDark ? '#f9fafb' : '#111827'} />\n            <span style={{ fontSize: isTouch ? 15 : 13, fontWeight: 500, letterSpacing: '0.01em' }}>\n              {isEditing ? 'Updating...' : 'Sending...'}\n            </span>\n          </>\n        ) : (\n          <>\n            <ThumbsDownIcon size={iconSize} />\n            <span style={{ fontSize: isTouch ? 15 : 13, fontWeight: 500, letterSpacing: '0.01em' }}>\n              {labels?.down || (previousVote === 'down' ? 'Disliked' : 'Dislike')}\n            </span>\n          </>\n        )}\n      </button>\n    </div>\n  );\n}\n\nfunction ThumbsUpIcon({ size = 24 }: { size?: number }) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\" />\n    </svg>\n  );\n}\n\nfunction ThumbsDownIcon({ size = 24 }: { size?: number }) {\n  return (\n    <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\" />\n    </svg>\n  );\n}\n","import React, { useState, useEffect } from 'react';\nimport { isTouchDevice } from '../../utils/device';\nimport { Spinner } from '../Spinner';\n\ninterface PollModeProps {\n  theme: 'light' | 'dark' | 'custom';\n  options: string[];\n  allowMultiple: boolean;\n  isLoading: boolean;\n  onSubmit: (data: { pollSelected: string[] }) => void;\n  initialSelected?: string[] | null;\n  isEditing?: boolean;\n}\n\nexport function PollMode({\n  theme,\n  options,\n  allowMultiple,\n  isLoading,\n  onSubmit,\n  initialSelected,\n  isEditing = false,\n}: PollModeProps) {\n  const [selected, setSelected] = useState<string[]>(initialSelected || []);\n  const [isTouch, setIsTouch] = useState(false);\n\n  useEffect(() => {\n    setIsTouch(isTouchDevice());\n  }, []);\n\n  useEffect(() => {\n    if (initialSelected) {\n      setSelected(initialSelected);\n    }\n  }, [initialSelected]);\n\n  const isDark = theme === 'dark';\n\n  const handleToggle = (option: string) => {\n    if (allowMultiple) {\n      setSelected((prev) =>\n        prev.includes(option) ? prev.filter((o) => o !== option) : [...prev, option]\n      );\n    } else {\n      setSelected((prev) => (prev.includes(option) ? [] : [option]));\n    }\n  };\n\n  const handleSubmit = () => {\n    if (selected.length === 0) return;\n    onSubmit({ pollSelected: selected });\n  };\n\n  const getOptionStyles = (option: string): React.CSSProperties => {\n    const isSelected = selected.includes(option);\n    return {\n      width: '100%',\n      padding: isTouch ? '12px 14px' : '9px 12px',\n      border: `1px solid ${isSelected\n        ? (isDark ? 'rgba(226,232,240,0.25)' : 'rgba(30,41,59,0.25)')\n        : (isDark ? 'rgba(255,255,255,0.08)' : '#e2e8f0')}`,\n      borderRadius: isTouch ? 10 : 8,\n      backgroundColor: isSelected\n        ? (isDark ? 'rgba(226,232,240,0.08)' : 'rgba(30,41,59,0.05)')\n        : (isDark ? 'rgba(55,65,81,0.5)' : '#fafbfc'),\n      color: isSelected\n        ? (isDark ? '#e2e8f0' : '#1e293b')\n        : (isDark ? '#d1d5db' : '#374151'),\n      fontSize: isTouch ? 15 : 13,\n      fontWeight: 500,\n      cursor: isLoading ? 'not-allowed' : 'pointer',\n      transition: 'background-color 0.2s, border-color 0.2s, color 0.2s',\n      textAlign: 'left' as const,\n      letterSpacing: '0.01em',\n      display: 'flex',\n      alignItems: 'center',\n      gap: 8,\n    };\n  };\n\n  return (\n    <div>\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: isTouch ? 8 : 6,\n        }}\n        role=\"group\"\n        aria-label={allowMultiple ? 'Select one or more options' : 'Select an option'}\n      >\n        {options.map((option) => {\n          const isSelected = selected.includes(option);\n          return (\n            <button\n              key={option}\n              type=\"button\"\n              onClick={() => handleToggle(option)}\n              disabled={isLoading}\n              style={getOptionStyles(option)}\n              aria-pressed={isSelected}\n            >\n              <span\n                style={{\n                  width: 16,\n                  height: 16,\n                  borderRadius: allowMultiple ? 4 : '50%',\n                  border: `2px solid ${isSelected\n                    ? (isDark ? '#e2e8f0' : '#1e293b')\n                    : (isDark ? 'rgba(255,255,255,0.2)' : '#cbd5e1')}`,\n                  backgroundColor: isSelected\n                    ? (isDark ? '#e2e8f0' : '#1e293b')\n                    : 'transparent',\n                  display: 'flex',\n                  alignItems: 'center',\n                  justifyContent: 'center',\n                  flexShrink: 0,\n                  transition: 'all 0.15s',\n                }}\n              >\n                {isSelected && (\n                  <svg width={10} height={10} viewBox=\"0 0 12 12\" fill=\"none\">\n                    <path\n                      d=\"M2 6l3 3 5-5\"\n                      stroke=\"#fff\"\n                      strokeWidth=\"2\"\n                      strokeLinecap=\"round\"\n                      strokeLinejoin=\"round\"\n                    />\n                  </svg>\n                )}\n              </span>\n              {option}\n            </button>\n          );\n        })}\n      </div>\n\n      <button\n        type=\"button\"\n        onClick={handleSubmit}\n        disabled={isLoading || selected.length === 0}\n        style={{\n          width: '100%',\n          marginTop: 12,\n          padding: isTouch ? '14px 16px' : '10px 16px',\n          border: 'none',\n          borderRadius: 8,\n          backgroundColor: selected.length === 0\n            ? (isDark ? '#374151' : '#e2e8f0')\n            : (isDark ? '#e2e8f0' : '#1e293b'),\n          color: selected.length === 0\n            ? (isDark ? '#6b7280' : '#94a3b8')\n            : (isDark ? '#1e293b' : '#ffffff'),\n          fontSize: isTouch ? 16 : 14,\n          fontWeight: 500,\n          cursor: isLoading || selected.length === 0 ? 'not-allowed' : 'pointer',\n          transition: 'all 0.2s cubic-bezier(0.4, 0, 0.2, 1)',\n          letterSpacing: '0.01em',\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'center',\n          gap: 8,\n          opacity: isLoading ? 0.8 : 1,\n        }}\n        onMouseEnter={(e) => {\n          if (!e.currentTarget.disabled) {\n            e.currentTarget.style.backgroundColor = isDark ? '#cbd5e1' : '#334155';\n          }\n        }}\n        onMouseLeave={(e) => {\n          if (!e.currentTarget.disabled) {\n            e.currentTarget.style.backgroundColor = selected.length === 0\n              ? (isDark ? '#374151' : '#e2e8f0')\n              : (isDark ? '#e2e8f0' : '#1e293b');\n          }\n        }}\n      >\n        {isLoading && <Spinner size={isTouch ? 18 : 16} color={isDark ? '#1e293b' : '#ffffff'} />}\n        {isLoading ? (isEditing ? 'Updating...' : 'Submitting...') : (isEditing ? 'Update' : 'Submit')}\n      </button>\n    </div>\n  );\n}\n","import React, { useRef, useEffect, useState } from 'react';\nimport { Theme, GotchaStyles, ResponseMode, ExistingResponse } from '../types';\nimport { cn } from '../utils/cn';\nimport { FeedbackMode } from './modes/FeedbackMode';\nimport { VoteMode } from './modes/VoteMode';\nimport { PollMode } from './modes/PollMode';\n\nexport interface GotchaModalProps {\n  mode: ResponseMode;\n  theme: Theme;\n  customStyles?: GotchaStyles;\n  promptText?: string;\n  placeholder?: string;\n  submitText: string;\n  thankYouMessage: string;\n  // State\n  isLoading: boolean;\n  isSubmitted: boolean;\n  error: string | null;\n  // Edit mode\n  existingResponse?: ExistingResponse | null;\n  isEditing?: boolean;\n  // Vote mode\n  voteLabels?: { up: string; down: string };\n  // Poll mode\n  options?: string[];\n  allowMultiple?: boolean;\n  // Handlers\n  onSubmit: (data: { content?: string; rating?: number; vote?: 'up' | 'down'; pollSelected?: string[] }) => void;\n  onClose: () => void;\n  // Position info from parent\n  anchorRect?: DOMRect;\n}\n\nexport function GotchaModal({\n  mode,\n  theme,\n  customStyles,\n  promptText,\n  placeholder,\n  submitText,\n  thankYouMessage,\n  isLoading,\n  isSubmitted,\n  error,\n  existingResponse,\n  isEditing = false,\n  voteLabels,\n  options,\n  allowMultiple = false,\n  onSubmit,\n  onClose,\n  anchorRect,\n}: GotchaModalProps) {\n  const modalRef = useRef<HTMLDivElement>(null);\n  const firstFocusableRef = useRef<HTMLButtonElement>(null);\n  const [isVisible, setIsVisible] = useState(false);\n  const [isMobile, setIsMobile] = useState(false);\n  const [systemTheme, setSystemTheme] = useState<'light' | 'dark'>('light');\n\n  // Detect mobile and system theme after mount (SSR-safe)\n  useEffect(() => {\n    setIsMobile(window.innerWidth < 640);\n\n    // Detect system theme preference\n    const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');\n    setSystemTheme(darkQuery.matches ? 'dark' : 'light');\n\n    // Listen for theme changes\n    const handler = (e: MediaQueryListEvent) => setSystemTheme(e.matches ? 'dark' : 'light');\n    darkQuery.addEventListener('change', handler);\n    return () => darkQuery.removeEventListener('change', handler);\n  }, []);\n\n  // Trigger animation after mount\n  useEffect(() => {\n    const timer = requestAnimationFrame(() => setIsVisible(true));\n    return () => cancelAnimationFrame(timer);\n  }, []);\n\n  // Resolve theme\n  const resolvedTheme = theme === 'auto' ? systemTheme : theme;\n\n  const isDark = resolvedTheme === 'dark';\n\n  // Determine if modal should appear above or below\n  const modalHeight = 280; // approximate modal height\n  const spaceBelow = anchorRect\n    ? window.innerHeight - anchorRect.bottom\n    : window.innerHeight / 2;\n  const showAbove = spaceBelow < modalHeight + 20;\n\n  // Focus trap\n  useEffect(() => {\n    const modal = modalRef.current;\n    if (!modal) return;\n\n    // Focus first element\n    firstFocusableRef.current?.focus();\n\n    const handleKeyDown = (e: KeyboardEvent) => {\n      if (e.key === 'Escape') {\n        onClose();\n        return;\n      }\n\n      if (e.key === 'Tab') {\n        const focusableElements = modal.querySelectorAll<HTMLElement>(\n          'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n        );\n        const firstElement = focusableElements[0];\n        const lastElement = focusableElements[focusableElements.length - 1];\n\n        if (e.shiftKey && document.activeElement === firstElement) {\n          e.preventDefault();\n          lastElement?.focus();\n        } else if (!e.shiftKey && document.activeElement === lastElement) {\n          e.preventDefault();\n          firstElement?.focus();\n        }\n      }\n    };\n\n    document.addEventListener('keydown', handleKeyDown);\n    return () => document.removeEventListener('keydown', handleKeyDown);\n  }, [onClose]);\n\n  const defaultPrompt = mode === 'vote'\n    ? 'What do you think?'\n    : mode === 'poll'\n    ? 'Cast your vote'\n    : 'What do you think of this feature?';\n\n  // Responsive sizing - on mobile, use fixed positioning centered on screen\n  const modalPadding = isMobile ? 20 : 16;\n\n  const layeredShadow = isDark\n    ? '0 1px 2px rgba(0,0,0,0.2), 0 4px 12px rgba(0,0,0,0.3), 0 12px 32px rgba(0,0,0,0.2)'\n    : '0 1px 2px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.06), 0 12px 32px rgba(0,0,0,0.06)';\n\n  const modalStyles: React.CSSProperties = isMobile\n    ? {\n        // Mobile: fixed position, centered on screen\n        position: 'fixed',\n        left: '50%',\n        top: '50%',\n        width: 'calc(100vw - 32px)',\n        maxWidth: 320,\n        padding: modalPadding,\n        borderRadius: 12,\n        backgroundColor: isDark ? '#1f2937' : '#ffffff',\n        color: isDark ? '#f9fafb' : '#111827',\n        boxShadow: layeredShadow,\n        border: `1px solid ${isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'}`,\n        zIndex: 9999,\n        transition: 'opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1)',\n        opacity: isVisible ? 1 : 0,\n        transform: isVisible\n          ? 'translate(-50%, -50%) scale(1)'\n          : 'translate(-50%, -50%) scale(0.96)',\n        ...customStyles?.modal,\n        textAlign: 'left',\n      }\n    : {\n        // Desktop: absolute position relative to button\n        position: 'absolute',\n        left: '50%',\n        width: 320,\n        padding: modalPadding,\n        borderRadius: 10,\n        backgroundColor: isDark ? '#1f2937' : '#ffffff',\n        color: isDark ? '#f9fafb' : '#111827',\n        boxShadow: layeredShadow,\n        border: `1px solid ${isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'}`,\n        zIndex: 9999,\n        ...(showAbove\n          ? { bottom: '100%', marginBottom: 8 }\n          : { top: '100%', marginTop: 8 }),\n        transition: 'opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1)',\n        opacity: isVisible ? 1 : 0,\n        transform: isVisible\n          ? 'translateX(-50%) scale(1) translateY(0)'\n          : `translateX(-50%) scale(0.96) translateY(${showAbove ? '6px' : '-6px'})`,\n        ...customStyles?.modal,\n        textAlign: 'left',\n      };\n\n  return (\n    <div\n      ref={modalRef}\n      role=\"dialog\"\n      aria-modal=\"true\"\n      aria-labelledby=\"gotcha-modal-title\"\n      style={modalStyles}\n      className={cn('gotcha-modal', isDark && 'gotcha-modal--dark')}\n    >\n      {/* Close button - larger on touch devices */}\n      <button\n        ref={firstFocusableRef}\n        type=\"button\"\n        onClick={onClose}\n        aria-label=\"Close feedback form\"\n        style={{\n          position: 'absolute',\n          top: isMobile ? 12 : 8,\n          right: isMobile ? 12 : 8,\n          width: isMobile ? 36 : 28,\n          height: isMobile ? 36 : 28,\n          border: 'none',\n          background: 'transparent',\n          cursor: 'pointer',\n          color: isDark ? '#6b7280' : '#9ca3af',\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'center',\n          borderRadius: 6,\n          transition: 'all 0.15s cubic-bezier(0.4, 0, 0.2, 1)',\n        }}\n        onMouseEnter={(e) => {\n          e.currentTarget.style.backgroundColor = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.04)';\n          e.currentTarget.style.color = isDark ? '#9ca3af' : '#6b7280';\n        }}\n        onMouseLeave={(e) => {\n          e.currentTarget.style.backgroundColor = 'transparent';\n          e.currentTarget.style.color = isDark ? '#6b7280' : '#9ca3af';\n        }}\n      >\n        <svg width={isMobile ? 16 : 12} height={isMobile ? 16 : 12} viewBox=\"0 0 14 14\" fill=\"none\">\n          <path\n            d=\"M1 1L13 13M1 13L13 1\"\n            stroke=\"currentColor\"\n            strokeWidth=\"1.5\"\n            strokeLinecap=\"round\"\n          />\n        </svg>\n      </button>\n\n      {/* Title */}\n      <h2\n        id=\"gotcha-modal-title\"\n        style={{\n          margin: '0 0 16px 0',\n          fontSize: isMobile ? 16 : 14,\n          fontWeight: 600,\n          paddingRight: isMobile ? 40 : 32,\n          letterSpacing: '-0.01em',\n          lineHeight: 1.4,\n          textAlign: 'left',\n        }}\n      >\n        {promptText || defaultPrompt}\n      </h2>\n\n      {/* Success state */}\n      {isSubmitted && (\n        <div\n          style={{\n            textAlign: 'center',\n            padding: '24px 0',\n            color: isDark ? '#10b981' : '#059669',\n          }}\n        >\n          <div\n            style={{\n              width: 44,\n              height: 44,\n              borderRadius: '50%',\n              backgroundColor: isDark ? 'rgba(16,185,129,0.1)' : 'rgba(5,150,105,0.08)',\n              display: 'flex',\n              alignItems: 'center',\n              justifyContent: 'center',\n              margin: '0 auto 12px',\n            }}\n          >\n            <svg\n              width=\"22\"\n              height=\"22\"\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n            >\n              <path\n                d=\"M20 6L9 17L4 12\"\n                stroke=\"currentColor\"\n                strokeWidth=\"2\"\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n              />\n            </svg>\n          </div>\n          <p style={{ margin: 0, fontSize: 13, fontWeight: 500, color: isDark ? '#d1d5db' : '#374151' }}>\n            {thankYouMessage}\n          </p>\n        </div>\n      )}\n\n      {/* Error state */}\n      {error && !isSubmitted && (\n        <div\n          style={{\n            padding: '8px 10px',\n            marginBottom: 12,\n            borderRadius: 8,\n            backgroundColor: isDark ? 'rgba(127,29,29,0.3)' : '#fef2f2',\n            border: `1px solid ${isDark ? 'rgba(254,202,202,0.1)' : 'rgba(220,38,38,0.1)'}`,\n            color: isDark ? '#fecaca' : '#dc2626',\n            fontSize: 13,\n            lineHeight: 1.4,\n          }}\n        >\n          {error}\n        </div>\n      )}\n\n      {/* Form content based on mode */}\n      {!isSubmitted && (\n        <>\n          {mode === 'feedback' && (\n            <FeedbackMode\n              theme={resolvedTheme}\n              placeholder={placeholder}\n              submitText={submitText}\n              isLoading={isLoading}\n              onSubmit={onSubmit}\n              customStyles={customStyles}\n              initialValues={existingResponse ? {\n                content: existingResponse.content,\n                rating: existingResponse.rating,\n              } : undefined}\n              isEditing={isEditing}\n            />\n          )}\n          {mode === 'vote' && (\n            <VoteMode\n              theme={resolvedTheme}\n              isLoading={isLoading}\n              onSubmit={onSubmit}\n              initialVote={existingResponse?.vote || undefined}\n              isEditing={isEditing}\n              labels={voteLabels}\n            />\n          )}\n          {mode === 'poll' && options && options.length > 0 && (\n            <PollMode\n              theme={resolvedTheme}\n              options={options}\n              allowMultiple={allowMultiple}\n              isLoading={isLoading}\n              onSubmit={onSubmit}\n              initialSelected={existingResponse?.pollSelected || undefined}\n              isEditing={isEditing}\n            />\n          )}\n        </>\n      )}\n\n      {/* Screen reader announcement */}\n      <div aria-live=\"polite\" className=\"sr-only\" style={{ position: 'absolute', left: -9999 }}>\n        {isSubmitted && 'Thank you! Your feedback has been submitted.'}\n        {error && `Error: ${error}`}\n      </div>\n    </div>\n  );\n}\n","import React, { useState, useCallback, useEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n  ResponseMode,\n  GotchaUser,\n  Position,\n  Size,\n  Theme,\n  TouchBehavior,\n  GotchaStyles,\n  GotchaResponse,\n  GotchaError,\n} from '../types';\nimport { DEFAULTS } from '../constants';\nimport { useGotchaContext } from './GotchaProvider';\nimport { useSubmit } from '../hooks/useSubmit';\nimport { GotchaButton } from './GotchaButton';\nimport { GotchaModal } from './GotchaModal';\n\nexport interface GotchaProps {\n  /** Unique identifier for this element */\n  elementId: string;\n\n  // User data\n  /** User metadata for segmentation */\n  user?: GotchaUser;\n\n  // Behavior\n  /** Feedback mode */\n  mode?: ResponseMode;\n  /** Required if mode is 'ab' */\n  experimentId?: string;\n  /** Current A/B variant shown to user */\n  variant?: string;\n\n  // Vote mode specific\n  /** Custom labels for vote buttons (default: Like/Dislike) */\n  voteLabels?: { up: string; down: string };\n\n  // Poll mode specific (Phase 2)\n  /** Required if mode is 'poll' (2-6 options) */\n  options?: string[];\n  /** Allow selecting multiple options */\n  allowMultiple?: boolean;\n  /** Show results after voting */\n  showResults?: boolean;\n\n  // Appearance\n  /** Button position relative to parent */\n  position?: Position;\n  /** Button size */\n  size?: Size;\n  /** Color theme */\n  theme?: Theme;\n  /** Custom style overrides */\n  customStyles?: GotchaStyles;\n  /** Control visibility programmatically */\n  visible?: boolean;\n  /** Only show when parent is hovered (default: true) */\n  showOnHover?: boolean;\n  /** Mobile behavior (default: 'always-visible') */\n  touchBehavior?: TouchBehavior;\n\n  // Content\n  /** Custom prompt text */\n  promptText?: string;\n  /** Input placeholder text */\n  placeholder?: string;\n  /** Submit button text */\n  submitText?: string;\n  /** Post-submission message */\n  thankYouMessage?: string;\n\n  // Callbacks\n  /** Called after successful submission */\n  onSubmit?: (response: GotchaResponse) => void;\n  /** Called when modal opens */\n  onOpen?: () => void;\n  /** Called when modal closes */\n  onClose?: () => void;\n  /** Called on error */\n  onError?: (error: GotchaError) => void;\n}\n\nexport function Gotcha({\n  elementId,\n  user,\n  mode = 'feedback',\n  experimentId,\n  variant,\n  voteLabels,\n  options,\n  allowMultiple = false,\n  showResults = true,\n  position = DEFAULTS.POSITION,\n  size = DEFAULTS.SIZE,\n  theme = DEFAULTS.THEME,\n  customStyles,\n  visible = true,\n  showOnHover = DEFAULTS.SHOW_ON_HOVER,\n  touchBehavior = DEFAULTS.TOUCH_BEHAVIOR,\n  promptText,\n  placeholder,\n  submitText = DEFAULTS.SUBMIT_TEXT,\n  thankYouMessage = DEFAULTS.THANK_YOU_MESSAGE,\n  onSubmit,\n  onOpen,\n  onClose,\n  onError,\n}: GotchaProps) {\n  const { disabled, activeModalId, openModal, closeModal } = useGotchaContext();\n  const [isSubmitted, setIsSubmitted] = useState(false);\n  const [isParentHovered, setIsParentHovered] = useState(false);\n  const [anchorRect, setAnchorRect] = useState<DOMRect | null>(null);\n  const [isMobile, setIsMobile] = useState(false);\n  const containerRef = useRef<HTMLDivElement>(null);\n\n  // Detect mobile for portal rendering (SSR-safe)\n  useEffect(() => {\n    setIsMobile(window.innerWidth < 640);\n  }, []);\n\n  // This instance's modal is open if activeModalId matches our elementId\n  const isOpen = activeModalId === elementId;\n\n  // Attach hover listeners to the parent element (not the button container)\n  useEffect(() => {\n    if (!showOnHover) return;\n\n    const container = containerRef.current;\n    if (!container) return;\n\n    // Find the parent element with position: relative\n    const parent = container.parentElement;\n    if (!parent) return;\n\n    const handleMouseEnter = () => setIsParentHovered(true);\n    const handleMouseLeave = () => setIsParentHovered(false);\n\n    parent.addEventListener('mouseenter', handleMouseEnter);\n    parent.addEventListener('mouseleave', handleMouseLeave);\n\n    return () => {\n      parent.removeEventListener('mouseenter', handleMouseEnter);\n      parent.removeEventListener('mouseleave', handleMouseLeave);\n    };\n  }, [showOnHover]);\n\n  const { submit, isLoading, error, existingResponse, isEditing } = useSubmit({\n    elementId,\n    mode,\n    experimentId,\n    variant,\n    pollOptions: options,\n    user,\n    onSuccess: (response) => {\n      setIsSubmitted(true);\n      onSubmit?.(response);\n      // Auto-close after 3 seconds\n      setTimeout(() => {\n        closeModal();\n        setIsSubmitted(false);\n      }, 3000);\n    },\n    onError: (err) => {\n      console.warn('[Gotcha] Submission failed:', err instanceof Error ? err.message : err);\n      onError?.(err as unknown as GotchaError);\n    },\n  });\n\n  const handleOpen = useCallback(() => {\n    if (containerRef.current) {\n      setAnchorRect(containerRef.current.getBoundingClientRect());\n    }\n    openModal(elementId);\n    onOpen?.();\n  }, [elementId, openModal, onOpen]);\n\n  const handleClose = useCallback(() => {\n    closeModal();\n    setIsSubmitted(false);\n    onClose?.();\n  }, [closeModal, onClose]);\n\n  const handleSubmit = useCallback(\n    (data: { content?: string; rating?: number; vote?: 'up' | 'down'; pollSelected?: string[] }) => {\n      submit(data);\n    },\n    [submit]\n  );\n\n  // Don't render if disabled or not visible\n  if (disabled || !visible) return null;\n\n  // Position styles\n  const positionStyles: Record<Position, React.CSSProperties> = {\n    'top-right': { position: 'absolute', top: 0, right: 0, transform: 'translate(50%, -50%)' },\n    'top-left': { position: 'absolute', top: 0, left: 0, transform: 'translate(-50%, -50%)' },\n    'bottom-right': { position: 'absolute', bottom: 0, right: 0, transform: 'translate(50%, 50%)' },\n    'bottom-left': { position: 'absolute', bottom: 0, left: 0, transform: 'translate(-50%, 50%)' },\n    'inline': { position: 'relative', display: 'inline-flex' },\n  };\n\n  return (\n    <div\n      ref={containerRef}\n      style={{\n        ...positionStyles[position],\n        zIndex: isOpen ? 10000 : 'auto',\n      }}\n      className=\"gotcha-container\"\n      data-gotcha-element={elementId}\n    >\n      <GotchaButton\n        size={size}\n        theme={theme}\n        customStyles={customStyles}\n        showOnHover={showOnHover}\n        touchBehavior={touchBehavior}\n        onClick={handleOpen}\n        isOpen={isOpen}\n        isParentHovered={isParentHovered}\n      />\n\n      {isOpen && !isMobile && (\n        <GotchaModal\n          mode={mode}\n          theme={theme}\n          customStyles={customStyles}\n          promptText={promptText}\n          placeholder={placeholder}\n          submitText={submitText}\n          thankYouMessage={isEditing ? 'Your feedback has been updated!' : thankYouMessage}\n          isLoading={isLoading}\n          isSubmitted={isSubmitted}\n          error={error}\n          existingResponse={existingResponse}\n          isEditing={isEditing}\n          voteLabels={voteLabels}\n          options={options}\n          allowMultiple={allowMultiple}\n          onSubmit={handleSubmit}\n          onClose={handleClose}\n          anchorRect={anchorRect || undefined}\n        />\n      )}\n\n      {/* On mobile, render modal via portal to escape parent transform */}\n      {isOpen && isMobile && createPortal(\n        <div\n          style={{\n            position: 'fixed',\n            inset: 0,\n            zIndex: 99999,\n            backgroundColor: 'rgba(0, 0, 0, 0.3)',\n          }}\n          onClick={handleClose}\n          aria-hidden=\"true\"\n        >\n          <div onClick={(e) => e.stopPropagation()}>\n            <GotchaModal\n              mode={mode}\n              theme={theme}\n              customStyles={customStyles}\n              promptText={promptText}\n              placeholder={placeholder}\n              submitText={submitText}\n              thankYouMessage={isEditing ? 'Your feedback has been updated!' : thankYouMessage}\n              isLoading={isLoading}\n              isSubmitted={isSubmitted}\n              error={error}\n              existingResponse={existingResponse}\n              isEditing={isEditing}\n              voteLabels={voteLabels}\n              options={options}\n              allowMultiple={allowMultiple}\n              onSubmit={handleSubmit}\n              onClose={handleClose}\n              anchorRect={anchorRect || undefined}\n            />\n          </div>\n        </div>,\n        document.body\n      )}\n    </div>\n  );\n}\n","import { useGotchaContext } from '../components/GotchaProvider';\n\n/**\n * Hook to access Gotcha context\n * Must be used within a GotchaProvider\n */\nexport function useGotcha() {\n  const { client, disabled, defaultUser, debug } = useGotchaContext();\n\n  return {\n    /** The API client for manual submissions */\n    client,\n    /** Whether Gotcha is globally disabled */\n    disabled,\n    /** Default user metadata */\n    defaultUser,\n    /** Whether debug mode is enabled */\n    debug,\n    /** Submit feedback programmatically */\n    submitFeedback: client.submitResponse.bind(client),\n  };\n}\n"]}