/** * The accessible feedback channel of the capture visualizer: a visible instruction plate * (aria-hidden) plus visually hidden live regions for the screen reader. * * A message must stay unchanged for settleMs before it counts. The plate then shows it right away, * while the spoken channel changes no faster than the screen reader can speak the previous * message; intermediate messages are dropped rather than queued. */ export declare class FeedbackAnnouncer { private static readonly settleMs; private static readonly minIntervalMs; private static readonly maxIntervalMs; private static readonly msPerWord; private static readonly owners; private container; private visibleTextEl; private politeRegion; private alertRegion; private pending; private settled; private spoken; private settleTimer; private voiceTimer; private spokenStep; private spokenText; private plateVisible; private lastSpokenAt; constructor(containerElement: HTMLElement); /** Call on every processed frame. immediate skips the settle window and the pacing gate, * assertive marks the outcome of the flow, which also interrupts the screen reader. */ setMessage(instruction: string, step: string, immediate?: boolean, assertive?: boolean): void; /** Hiding the plate does not silence the spoken channel: not drawing text over the camera view * must not take the guidance away from a screen reader. */ setPlateVisible(visible: boolean): void; /** Stop the timers and clear the visible plate. The DOM nodes stay in the container: a live * region has to exist before it is written, so re-inserting it at the start of every capture * would cost the first announcement (iOS VoiceOver in particular). */ reset(): void; private forgetSpoken; private isOwner; private stopTimer; private createOrReuseNodes; /** Visually hidden by a 1px clipped box, NOT display:none - that would drop the region from * the accessibility tree. */ private createLiveRegion; private writePlate; private writeLive; /** Time a screen reader needs to speak the text, used as the gap before the next message. */ private static speakTimeMs; /** Speak the settled message once the pacing gate opens; silence and immediate messages skip * it. Whatever is settled when the gate opens wins, so intermediate messages are dropped. */ private scheduleVoice; private speak; } //# sourceMappingURL=feedback-announcer.d.ts.map