/**
 * Framework-agnostic base prop types for all refraction-ui components.
 * These are headless core types — no React or Astro imports.
 * Framework wrappers extend these with framework-specific types.
 */
/** Base props shared by all components */
interface BaseProps {
    id?: string;
    className?: string;
    style?: Record<string, string | number>;
    [dataAttr: `data-${string}`]: string | undefined;
}
/** Accessibility props */
interface AccessibilityProps {
    role?: string;
    tabIndex?: number;
    'aria-label'?: string;
    'aria-labelledby'?: string;
    'aria-describedby'?: string;
    'aria-controls'?: string;
    'aria-expanded'?: boolean;
    'aria-selected'?: boolean;
    'aria-hidden'?: boolean;
    'aria-disabled'?: boolean;
    'aria-pressed'?: boolean | 'mixed';
    'aria-checked'?: boolean | 'mixed';
    'aria-current'?: boolean | 'page' | 'step' | 'location' | 'date' | 'time';
    'aria-live'?: 'off' | 'assertive' | 'polite';
    'aria-atomic'?: boolean;
}
/** Theme customization props (framework-agnostic) */
interface ThemeProps {
    variant?: string;
    size?: string;
    colorScheme?: string;
    disabled?: boolean;
}
/** Composition props (framework-agnostic) */
interface CompositionProps {
    asChild?: boolean;
}

/** Standard size scale */
type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
/** Standard component variants */
type Variant = 'default' | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'link';
/** Layout orientation */
type Orientation = 'horizontal' | 'vertical';
/** Positioning side */
type Side = 'top' | 'right' | 'bottom' | 'left';
/** Alignment */
type Align = 'start' | 'center' | 'end';
/** Data state attribute values */
type DataState = 'open' | 'closed' | 'active' | 'inactive';

/** Defines the CSS custom properties a component reads */
interface TokenContract {
    /** Component name */
    name: string;
    /** Map of token name → CSS custom property info */
    tokens: Record<string, TokenDefinition>;
}
interface TokenDefinition {
    /** CSS custom property name (e.g., '--rfr-button-bg') */
    variable: string;
    /** Fallback value when the variable is not set */
    fallback: string;
    /** Description of what this token controls */
    description?: string;
}

/** Standard keyboard key constants */
declare const Keys: {
    readonly Enter: "Enter";
    readonly Space: " ";
    readonly Escape: "Escape";
    readonly Tab: "Tab";
    readonly ArrowUp: "ArrowUp";
    readonly ArrowDown: "ArrowDown";
    readonly ArrowLeft: "ArrowLeft";
    readonly ArrowRight: "ArrowRight";
    readonly Home: "Home";
    readonly End: "End";
    readonly PageUp: "PageUp";
    readonly PageDown: "PageDown";
    readonly Backspace: "Backspace";
    readonly Delete: "Delete";
};
type KeyboardKey = (typeof Keys)[keyof typeof Keys];
/** Map of key → handler function */
type KeyboardHandlerMap = Partial<Record<string, (event: KeyboardEvent) => void>>;
/** Create a keyboard event handler from a handler map */
declare function createKeyboardHandler(handlers: KeyboardHandlerMap): (event: KeyboardEvent) => void;

/**
 * Minimal state machine — zero dependencies, < 1KB.
 * Inspired by XState concepts but dramatically simpler.
 */
interface MachineConfig<TState extends string, TEvent extends string> {
    initial: TState;
    states: Record<TState, {
        on?: Partial<Record<TEvent, TState>>;
    }>;
}
interface Machine<TState extends string, TEvent extends string> {
    /** Current state */
    state: TState;
    /** Send an event to transition */
    send(event: TEvent): void;
    /** Subscribe to state changes. Returns unsubscribe function. */
    subscribe(fn: (state: TState) => void): () => void;
    /** Check if machine is in a given state */
    matches(state: TState): boolean;
}
declare function createMachine<TState extends string, TEvent extends string>(config: MachineConfig<TState, TEvent>): Machine<TState, TEvent>;

/**
 * Focus trap utilities — keeps keyboard focus within a container.
 * Used by Dialog, DropdownMenu, and other overlay components.
 * Pure TypeScript, no DOM dependency (accepts element via parameter).
 */
/** Selector for all natively focusable elements */
declare const FOCUSABLE_SELECTOR = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
/** Get all focusable elements within a container */
declare function getFocusableElements(container: Element): Element[];
/** Configuration for creating a focus trap */
interface FocusTrapConfig {
    /** The container element */
    container: Element;
    /** Called to get the initial focus target */
    initialFocus?: () => Element | null;
    /** Called when Escape is pressed */
    onEscape?: () => void;
    /** Whether to return focus to trigger on deactivate */
    returnFocusOnDeactivate?: boolean;
}
/** A focus trap instance */
interface FocusTrap {
    activate(): void;
    deactivate(): void;
    isActive(): boolean;
}
/** Create a focus trap that keeps Tab/Shift+Tab within a container */
declare function createFocusTrap(config: FocusTrapConfig): FocusTrap;

/**
 * Screen reader announcement utility.
 * Creates and manages an aria-live region for dynamic content updates.
 */
interface LiveRegionConfig {
    /** 'polite' (default) or 'assertive' */
    politeness?: 'polite' | 'assertive';
    /** Clear the announcement after this many ms. Default: 5000 */
    clearAfterMs?: number;
}
interface LiveRegion {
    announce(message: string): void;
    clear(): void;
    destroy(): void;
}
/** Create a live region that announces messages to screen readers */
declare function createLiveRegion(config?: LiveRegionConfig): LiveRegion;

interface EngineAdapter<TState = Record<string, unknown>, TMethods = Record<string, unknown>, TReturnProps = Record<string, unknown>> {
    name: string;
    state: TState;
    methods: TMethods;
    getProps: (elementName: string, props?: Record<string, unknown>) => TReturnProps;
}

/**
 * Skip-to-content link utility.
 * Provides a keyboard-accessible link that is visually hidden until focused.
 */
/** Props for a skip-to-content link */
interface SkipLinkProps {
    /** ID of the target element. Default: 'main-content' */
    targetId?: string;
    /** Label text for the link. Default: 'Skip to main content' */
    label?: string;
}
/** Create props for a skip-to-content link */
declare function createSkipLink(props?: SkipLinkProps): {
    ariaProps: Record<string, string>;
    href: string;
    label: string;
    /** CSS classes — visually hidden until focused */
    className: string;
};

/**
 * dev-feedback — zero-dependency `devWarn` / `devError` primitives.
 *
 * Design constraints (epic #247, issue #248):
 * - Guarded by `process.env.NODE_ENV !== 'production'` so production bundlers
 *   dead-code-strip every call (the guard is a static string compare that
 *   minifiers fold to `false` in prod builds).
 * - Warn-once dedupe per `code` — a footgun is reported once, not on every
 *   render.
 * - NO import of `@refraction-ui/logger` (no hard dependency on the telemetry
 *   lib). Forwarding to a telemetry sink happens ONLY if the consumer
 *   explicitly injects one (dependency inversion, never an import).
 */
/**
 * Minimal structural shape of the record a telemetry sink consumes. This is a
 * deliberate structural mirror of `@refraction-ui/logger`'s `LogRecord` — it is
 * NOT imported, so `@refraction-ui/shared` keeps zero dependency on the
 * telemetry lib. A consumer that wires the real logger sink satisfies this
 * shape structurally.
 */
interface DevFeedbackRecord {
    level: 'warn' | 'error';
    message: string;
    timestamp: number;
    /** Structured detail — the library-origin envelope lives here. */
    context: Record<string, unknown>;
}
/**
 * The narrow contract a consumer-injected telemetry sink must satisfy. Kept
 * intentionally minimal and structural so the real `TelemetrySink` from
 * `@refraction-ui/logger` is assignable WITHOUT shared importing the logger.
 */
interface DevFeedbackSink {
    /** Receive a single dev-feedback record. Must never throw to the caller. */
    log(record: DevFeedbackRecord): void;
}
/**
 * Wire an optional telemetry sink that {@link devWarn} / {@link devError}
 * forward to (in addition to the console). Inversion of control: the consumer
 * owns the sink; this package never imports it. Pass `null` to unwire.
 *
 * Forwarding still only happens in non-production (the calls themselves are
 * stripped in prod), and still respects warn-once dedupe.
 */
declare function setDevFeedbackSink(sink: DevFeedbackSink | null): void;
/** Test-only / consumer-only escape hatch to reset warn-once dedupe state. */
declare function resetDevFeedback(): void;
/**
 * Emit a development-only warning for a refraction-ui footgun.
 *
 * @param code    Stable, greppable identifier (e.g. `'react/no-controlled-prop'`).
 * @param message Human-readable explanation.
 * @param detail  Optional structured detail (forwarded to an injected sink).
 *
 * Stripped entirely in production. Warned at most once per `code`.
 */
declare function devWarn(code: string, message: string, detail?: Record<string, unknown>): void;
/**
 * Emit a development-only error for a refraction-ui misuse / invariant break.
 *
 * @param code    Stable, greppable identifier.
 * @param message Human-readable explanation.
 * @param detail  Optional structured detail (forwarded to an injected sink).
 *
 * Stripped entirely in production. Reported at most once per `code`.
 */
declare function devError(code: string, message: string, detail?: Record<string, unknown>): void;

/**
 * library-origin-error — builds the **library-origin error envelope** for
 * errors that originate inside a `@refraction-ui/*` package.
 *
 * The envelope is expressed THROUGH the existing telemetry record contract
 * (`@refraction-ui/logger`'s `LogRecord`) — the contract is reused, NOT
 * redefined. To keep `@refraction-ui/shared` zero-dependency, the record is
 * mirrored structurally (see {@link DevFeedbackRecord}) rather than imported;
 * a consumer wiring the real logger sink satisfies it structurally.
 *
 * Aggressive redaction (epic #247 guardrails): the payload is package,
 * componentName, version, a normalized stack **fingerprint hash**, and
 * framework only. Never app state, props values, user data, PII, or full app
 * stack frames.
 */

/** Frameworks a refraction-ui adapter can run under. */
type LibraryFramework = 'react' | 'astro' | 'vue' | 'svelte' | 'vanilla' | 'unknown';
/** Inputs describing where a library-origin error came from. */
interface LibraryOriginErrorInput {
    /** Originating package, e.g. `@refraction-ui/react`. */
    package: string;
    /** refraction-ui component the error originated in, e.g. `Dialog`. */
    componentName: string;
    /** Originating package version, e.g. `0.1.5`. */
    version: string;
    /** Host framework the component was running under. */
    framework: LibraryFramework;
    /** The thrown error (or its stack string). Used ONLY to derive a hash. */
    error?: unknown;
}
/**
 * The redacted, library-origin payload carried in `LogRecord.context`. Contains
 * NO app data — only the five identifying fields plus a stack fingerprint hash.
 */
interface LibraryOriginEnvelope {
    /** Marks this record as a library-origin error (for downstream routing). */
    origin: 'refraction-ui';
    package: string;
    componentName: string;
    version: string;
    framework: LibraryFramework;
    /** Stable, app-data-free hash of the normalized stack. */
    fingerprint: string;
}
/**
 * Compute the stable stack fingerprint for a library-origin error. Exposed
 * separately so capture seams / tests can assert fingerprint stability without
 * building the whole record.
 */
declare function stackFingerprint(error: unknown): string;
/**
 * Build the redacted library-origin envelope for an error.
 */
declare function libraryOriginEnvelope(input: LibraryOriginErrorInput): LibraryOriginEnvelope;
/**
 * Build the full library-origin error record, expressed THROUGH the existing
 * telemetry record contract (`LogRecord`, mirrored as {@link DevFeedbackRecord}
 * to avoid a hard logger dependency). The redacted envelope rides in
 * `context`; no app data, props, PII, or app stack frames are included.
 *
 * This record is exactly what a consumer-wired telemetry sink (or the
 * `devWarn`/`devError` injected sink) consumes.
 */
declare function libraryOriginError(input: LibraryOriginErrorInput): DevFeedbackRecord;
/**
 * Library-origin predicate — `true` iff the error's stack contains at least
 * one frame that references a `@refraction-ui/*` package. This is the gate
 * every per-framework capture seam uses: only library-origin errors are
 * eligible; the app's own errors return `false` and pass through untouched.
 *
 * Mirrors exactly the frame-detection rule {@link stackFingerprint} normalizes
 * by — no new contract, just the companion predicate the seams need. Never
 * throws for a missing/odd error (returns `false`).
 */
declare function isLibraryOriginError(error: unknown): boolean;
/**
 * The fixed identity of the refraction-ui package/component a seam tags an
 * error with. The seam supplies this; the stack itself supplies the
 * fingerprint. Never carries app data.
 */
type LibraryOriginIdentity = Pick<LibraryOriginErrorInput, 'package' | 'componentName' | 'version' | 'framework'>;
/**
 * The single capture primitive shared by every per-framework seam (React error
 * boundary, Astro middleware). It performs the entire
 * guarded flow in one place so the seams stay thin and identical in behavior:
 *
 *  1. **Library-origin filter** — if the error's stack has no
 *     `@refraction-ui/*` frame it is the app's own error: return `null` and do
 *     NOT touch, capture, or forward it.
 *  2. **Tag** — build the redacted {@link libraryOriginError} record
 *     (package/componentName/version/framework + app-data-free fingerprint).
 *  3. **Route to the optional sink** — forward the record to the
 *     consumer-injected sink ONLY if one was wired; a broken sink can never
 *     break the consumer app. With no sink this is a no-op beyond returning
 *     the record (so a seam can still surface it locally).
 *
 * @returns the tagged record for a library-origin error, or `null` when the
 *          error is app-origin (the "pass through untouched" signal).
 */
declare function captureLibraryOriginError(error: unknown, identity: LibraryOriginIdentity, sink: DevFeedbackSink | null | undefined): DevFeedbackRecord | null;

/** Merge multiple ARIA prop objects, later values override earlier ones */
declare function mergeAriaProps(...propSets: Array<Record<string, unknown>>): Record<string, unknown>;
/**
 * Generate a unique ID, safe for SSR (deterministic within a render pass).
 * In browsers, uses crypto.randomUUID when available.
 */
declare function generateId(prefix?: string): string;
/** Reset the ID counter (useful for tests) */
declare function resetIdCounter(): void;

/**
 * Lightweight class name utility — our own implementation.
 * Handles conditional classes, arrays, and falsy values.
 * No external dependencies (no clsx, no tailwind-merge).
 *
 * For Tailwind class conflict resolution (e.g., 'p-2 p-4' → 'p-4'),
 * consumers can use @refraction-ui/tailwind-config which provides
 * a tw-merge-aware variant of this function.
 */
type ClassValue = string | number | boolean | undefined | null | ClassValue[];
type ClassRecord = Record<string, boolean | undefined | null>;
declare function cn(...inputs: Array<ClassValue | ClassRecord>): string;

/**
 * Lightweight class-variance-authority alternative — zero dependencies.
 * Creates variant-driven class name functions for components.
 */
interface VariantConfig {
    [variant: string]: Record<string, string>;
}
interface CVAConfig<V extends VariantConfig> {
    base?: string;
    variants?: V;
    defaultVariants?: {
        [K in keyof V]?: keyof V[K];
    };
    compoundVariants?: Array<{
        [K in keyof V]?: keyof V[K];
    } & {
        class: string;
    }>;
}
type VariantProps<V extends VariantConfig> = {
    [K in keyof V]?: keyof V[K];
};
declare function cva<V extends VariantConfig>(config: CVAConfig<V>): (props?: VariantProps<V> & {
    className?: string;
}) => string;

/**
 * Reduced motion utilities.
 * Respects user preferences for reduced motion.
 */
/** Check if user prefers reduced motion */
declare function prefersReducedMotion(): boolean;
/** Get animation duration — returns '0ms' if reduced motion preferred */
declare function getAnimationDuration(normalDuration: string): string;

export { type AccessibilityProps, type Align, type BaseProps, type CompositionProps, type DataState, type DevFeedbackRecord, type DevFeedbackSink, type EngineAdapter, FOCUSABLE_SELECTOR, type FocusTrap, type FocusTrapConfig, type KeyboardHandlerMap, type KeyboardKey, Keys, type LibraryFramework, type LibraryOriginEnvelope, type LibraryOriginErrorInput, type LibraryOriginIdentity, type LiveRegion, type LiveRegionConfig, type Machine, type MachineConfig, type Orientation, type Side, type Size, type SkipLinkProps, type ThemeProps, type TokenContract, type TokenDefinition, type Variant, captureLibraryOriginError, cn, createFocusTrap, createKeyboardHandler, createLiveRegion, createMachine, createSkipLink, cva, devError, devWarn, generateId, getAnimationDuration, getFocusableElements, isLibraryOriginError, libraryOriginEnvelope, libraryOriginError, mergeAriaProps, prefersReducedMotion, resetDevFeedback, resetIdCounter, setDevFeedbackSink, stackFingerprint };
