/**
 * Pure, DOM-free editing-affordance resolution. Single source of truth for what
 * the studio's edit panel (and any SDK consumer) surfaces per selected element:
 * capability flags + which section types apply. No getComputedStyle, no DOM —
 * the caller supplies normalized facts (live or static). See the SDK adapter
 * (browser-only) and the studio mapper for the two fact extractors.
 */
export interface DomEditCapabilities {
    canSelect: boolean;
    canEditStyles: boolean;
    /** Can take a non-destructive `clip-path: inset()` crop. Broader than
     *  canEditStyles: a sub-composition host can be cropped from the parent view
     *  (the crop is a viewport clip that persists on the host in the parent
     *  source), even though its internal styles are edited by drilling in. */
    canCrop: boolean;
    /** Directly editable authored left/top style fields. Canvas drag uses manual edits instead. */
    canMove: boolean;
    /** Directly editable authored width/height style fields. Canvas resize uses manual edits instead. */
    canResize: boolean;
    canApplyManualOffset: boolean;
    canApplyManualSize: boolean;
    canApplyManualRotation: boolean;
    reasonIfDisabled?: string;
}
export interface EditingSectionApplicability {
    text: boolean;
    media: boolean;
    /** Element-level only — the consumer still ANDs its own feature flag. */
    colorGrading: boolean;
    timing: boolean;
    animation: boolean;
    /** Position/size/rotation/stacking — meaningless on an element with no
     *  rendered box (e.g. `<audio>`, which never paints a visual frame). */
    layout: boolean;
    /** Audio FX chain and voiceover carve — `<audio>` only. Video carries its
     *  sound on a separate `<audio>` element, so this never applies to it. */
    audioFx: boolean;
    /** Fill/radius/stroke/shadow/blend-mode/clip — same "no rendered box" gate
     *  as `layout`, kept separate since a future tag could need one without
     *  the other. */
    style: boolean;
}
export interface EditingAffordances {
    capabilities: DomEditCapabilities;
    sections: EditingSectionApplicability;
}
export interface EditableElementFacts {
    /** A stable patch target exists (selector|hfId in studio; always true in the SDK model). */
    hasStableTarget: boolean;
    /** Lowercased tag name. */
    tag: string;
    /** kebab-case. Capability logic reads left/top/width/height/transform; sections read nothing here. */
    inlineStyles: Record<string, string>;
    /** kebab-case. Absent => canMove/canResize default to false (no live layout). */
    computedStyles?: Record<string, string>;
    isCompositionHost: boolean;
    isCompositionRoot: boolean;
    isInsideLockedComposition: boolean;
    isMasterView: boolean;
    existsInSource: boolean;
    /** studio: textFields.length > 0 ; SDK: model.text != null */
    hasEditableText: boolean;
    /** data-start present on the element */
    hasTimingStart: boolean;
    /** count of GSAP tweens targeting this element */
    animationCount: number;
}
/**
 * kebab-case px parser. Single source of truth — studio's domEditingDom
 * re-exports this so the two paths can't drift.
 */
export declare function parsePx(value: string | undefined): number | null;
/**
 * Section applicability only. Reads no style facts, so callers that already
 * hold resolved capabilities (e.g. the studio panel) can compute sections
 * without re-running the capability geometry parse.
 */
export declare function resolveEditingSections(facts: EditableElementFacts): EditingSectionApplicability;
export declare function resolveEditingAffordances(facts: EditableElementFacts): EditingAffordances;
//# sourceMappingURL=affordances.d.ts.map