/**
 * StackedCard resize policy — pure math.
 *
 * The card reports intent; the HOST applies a resize policy (spec §7). This
 * module is that policy, packaged as pure functions so the SAME code path
 * serves the pointer drag and the keyboard resize. Nothing here touches the
 * DOM, React or the card's content: it takes a start size, a delta and a
 * policy, and returns a clamped size. `useStackedCardResize` wires events to
 * it; the card's intrinsic content minimum is measured by the host and passed
 * in as `contentMin`, so this module knows nothing about heroes or footers.
 *
 * The policy has four parts:
 *  - bounds        — optional min/max per axis; unset means unbounded.
 *  - proportional  — lock the aspect ratio captured at the start of the gesture;
 *                    the scale is clamped by the BINDING axis so the ratio never
 *                    distorts at a bound.
 *  - step          — optional grid snap; proportion wins over the grid.
 *  - content min   — the effective min is max(policyMin, contentMin) per axis,
 *                    so a card can never be crushed below what its content needs.
 */
export interface StackedCardSize {
    w: number;
    h: number;
}
/** The card's intrinsic minimum, measured from its real content. */
export interface StackedCardContentMin {
    w: number;
    h: number;
}
export interface StackedCardResizePolicy {
    minW?: number;
    maxW?: number;
    minH?: number;
    maxH?: number;
    /** Lock the aspect ratio for the whole gesture. */
    proportional: boolean;
    /** Grid snap increment in px; omitted / 0 means continuous. */
    step?: number;
}
/** The size captured at the start of a gesture (pointer down or a key press). */
export interface StackedCardResizeStart {
    w: number;
    h: number;
    contentMin: StackedCardContentMin;
}
export interface StackedCardResizeDelta {
    dx: number;
    dy: number;
}
export interface StackedCardResizeBounds {
    wMin: number;
    wMax: number;
    hMin: number;
    hMax: number;
}
/**
 * `width` locks the vertical axis: an auto-height card takes a width and lets
 * its rows set the height, so the gesture's vertical component is ignored.
 */
export type StackedCardResizeAxis = "both" | "width";
/** Which input drove a resize event. Hosts log undo entries per source. */
export type StackedCardResizeSource = "pointer" | "keyboard";
/** Keyboard resize nudges by the policy step, or this when no step is set. */
export declare const DEFAULT_KEYBOARD_STEP = 8;
/** Shift + arrow resizes by a larger increment (the familiar coarse nudge). */
export declare const SHIFT_STEP_MULTIPLIER = 4;
/** Keys the separator handles; everything else falls through to the browser. */
export declare const RESIZE_KEYS: ReadonlyArray<string>;
export declare const isResizeKey: (key: string) => boolean;
export declare const clamp: (v: number, lo: number, hi?: number) => number;
export declare const snap: (v: number, step?: number) => number;
export declare const makeStart: (size: StackedCardSize, contentMin: StackedCardContentMin) => StackedCardResizeStart;
/**
 * The effective bounds a size is clamped to: the policy min floored by the
 * content min, and the policy max (unbounded when unset). Independent of any
 * live gesture, so a host can also use it for the aria value and Home/End.
 */
export declare const effectiveBounds: (policy: StackedCardResizePolicy, contentMin: StackedCardContentMin) => StackedCardResizeBounds;
/**
 * Apply a delta to the start size under the policy — the single path for both
 * inputs.
 *
 * `constrain` is the transient Shift-to-constrain lock: a free-form policy
 * behaves proportionally for that one gesture; a proportional policy is already
 * locked and ignores it. `axis: "width"` drops the gesture's vertical component;
 * the height then holds still in free-form mode, and still follows the ratio in
 * proportional mode (that is what proportional means).
 */
export declare const applyResize: (start: StackedCardResizeStart, delta: StackedCardResizeDelta, policy: StackedCardResizePolicy, opts?: {
    constrain?: boolean;
    axis?: StackedCardResizeAxis;
}) => StackedCardSize;
/**
 * Translate a resize key into the next size, reusing `applyResize` so the
 * keyboard clamps exactly like the pointer. Arrows nudge by the step (Shift ×4);
 * Home/End jump to the min/max of the allowed range, leaving any axis without
 * that bound where it is. Returns null for a key the handle does not own, and
 * for a vertical key on a width-only card.
 */
export declare const keyboardResize: (key: string, size: StackedCardSize, policy: StackedCardResizePolicy, contentMin: StackedCardContentMin, opts?: {
    shiftKey?: boolean;
    axis?: StackedCardResizeAxis;
}) => StackedCardSize | null;
/**
 * The handle's `aria-valuenow`: the current size as a percent (0–100) of its
 * allowed range. The corner resizes both axes, but the value must be a single
 * number, so it reports the WIDTH axis — the one axis the fixed-box and the
 * width-only cards share. Returns 0 when the range isn't finite (no max bound).
 */
export declare const measurePercent: (size: StackedCardSize, policy: StackedCardResizePolicy, contentMin: StackedCardContentMin) => number;
//# sourceMappingURL=resizePolicy.d.ts.map