/**
 * Marker attribute the default filter uses to exclude subtrees from a DOM-to-image capture.
 * Apply it to elements that should not appear in the rendered image — e.g. action toolbars
 * that would otherwise capture themselves.
 *
 * **Important**: do not apply this attribute to the capture root itself. The default filter
 * runs on every descendant *including* the root; marking the root excludes the entire subtree
 * and `toBlob()` returns `null`, surfacing as a "Copy failed" state in the UI. Consumers should
 * apply it to a child (typically the actions toolbar), never to the same node referenced by
 * `targetRef`.
 *
 * Lives in its own module so consumers like `chart-artifact.tsx` can import the string
 * constant without dragging in the heavy `dom-to-image.ts` module (font data URLs +
 * html-to-image). Re-exported from both `dom-to-image.ts` (for the default filter to read)
 * and `capture/index.ts` (for external consumers).
 */
declare const CAPTURE_EXCLUDE_ATTRIBUTE = "data-clay-capture-exclude";

/** Options for DOM-to-image conversions. Forwarded to `html-to-image`'s `toBlob`. */
interface NodeToImageOptions {
    /**
     * Background color filled before rasterising. Default: clay `white` token (`#FFFFFF`).
     * A solid background prevents the PNG from looking broken when pasted onto light or dark
     * surfaces (Slack, Notion, VS Code, etc.) — transparent PNGs render unpredictably.
     */
    backgroundColor?: string;
    /**
     * Device pixel ratio for retina-sharp output. Default: `window.devicePixelRatio || 1`.
     *
     * Memory implication: each copy allocates a canvas backing-store sized to
     * `width × height × pixelRatio²`. On a 3× HiDPI display a 480px-wide chart card produces a
     * ~1440px PNG (~8 MB allocation per copy). Single-click use is fine; batch-capture flows
     * ("copy every chart in this report") should pass `pixelRatio: 1` to avoid stacking spikes.
     */
    pixelRatio?: number;
    /**
     * Predicate run against every descendant element. Returning `false` excludes the node and
     * its subtree from the image. The clay default excludes any element marked with
     * `data-clay-capture-exclude` — caller-supplied filters compose with (not replace) the
     * default: a node is included only when both the default and the caller filter accept it.
     */
    filter?: (node: HTMLElement) => boolean;
    /** Override the captured width in pixels. Default: `node.offsetWidth`. */
    width?: number;
    /** Override the captured height in pixels. Default: `node.offsetHeight`. */
    height?: number;
    /**
     * Force-reload `<img>` sources to defeat stale-cache rendering. Default: `true`.
     * Note that this only cache-busts `<img>` `src` resources — fonts and CSS-referenced URLs
     * (e.g. `background-image: url(...)`) go through `html-to-image`'s separate global URL cache
     * which does NOT honor this flag.
     */
    cacheBust?: boolean;
    /**
     * Pre-resolved `@font-face` CSS so embedded text uses the correct fonts. When omitted, this
     * module resolves the document's font-embed CSS lazily on the first capture and reuses the
     * cached value thereafter — avoiding a recurring main-thread block to re-walk
     * `document.styleSheets` and re-base64-encode webfont files on every copy.
     */
    fontEmbedCSS?: string;
}
/**
 * Rasterise `node` to a PNG `Blob`. **Browser-only at call time**, but **import-safe under SSR**:
 * the module itself does not touch browser globals at module load, so a Node / SSR consumer can
 * `import { nodeToPngBlob } from "@shapesos/clay/capture"` without crashing. Calling any of the
 * three capture functions in a non-browser context throws — `nodeToPngBlob` references `<canvas>`
 * via `html-to-image`; `copyNodeAsPng` checks `ClipboardItem` / `navigator.clipboard` explicitly;
 * `downloadNodeAsPng` uses `URL.createObjectURL` + `document`. Guard at the call site with
 * `typeof window !== "undefined"` if you need to short-circuit SSR.
 *
 * Throws when `html-to-image` reports a null blob (browser couldn't rasterise) or when the
 * underlying conversion rejects.
 *
 * **Caveats** (worth knowing before adopting in a new artifact type):
 * - **Cross-origin tainting**: if the captured subtree contains a cross-origin `<img>`,
 *   `<image href>` SVG element, or any other resource the browser flags as cross-origin, the
 *   canvas is tainted and `toBlob()` returns `null` — surfaced as a "Failed to rasterise" error.
 *   This is browser-enforced; no clay-side fix exists. Ensure user-controlled annotations in
 *   chart subtrees don't reference cross-origin resources.
 * - **Global URL cache in the underlying library**: `html-to-image` maintains a module-global
 *   cache of image-src → base64. The cache is per-tab and lives for the SPA session. Today
 *   clay's only consumer (chart artifacts) renders SVG, so the cache stays empty in practice —
 *   but future artifact types that embed user-uploaded `<img>` content should be aware that
 *   image URLs are cached by URL, not by user identity.
 */
declare function nodeToPngBlob(node: HTMLElement, options?: NodeToImageOptions): Promise<Blob>;
/**
 * Rasterise `node` and write the resulting PNG to the system clipboard.
 *
 * Must be called from within a user gesture (button click, keypress) — browsers reject
 * clipboard writes from non-gesture contexts. The in-flight `Promise<Blob>` is passed
 * directly into `ClipboardItem` rather than awaited first, so Safari's "Blob must be
 * created during the user gesture" rule is satisfied.
 *
 * Throws when the clipboard API is unavailable (non-secure contexts: HTTP, certain embedded
 * frames), when the rasterise fails, or when the user has revoked clipboard-write permission.
 */
declare function copyNodeAsPng(node: HTMLElement, options?: NodeToImageOptions): Promise<void>;
/**
 * Rasterise `node` and trigger a browser file download of the resulting PNG. Uses an
 * `<a download>` with an object URL — the URL is revoked on a deferred timer so it doesn't
 * leak into the document for the lifetime of the tab but also isn't revoked before the
 * browser reads it.
 *
 * Must be called from a user gesture (the `<a>.click()` only triggers a download from inside one).
 *
 * @param filename The suggested filename presented to the user (e.g. `"chart-2026-05-25.png"`).
 *                 The `.png` extension is NOT appended automatically — callers control the full
 *                 filename so they can include titles, dates, or artifact IDs.
 */
declare function downloadNodeAsPng(node: HTMLElement, filename: string, options?: NodeToImageOptions): Promise<void>;

export { CAPTURE_EXCLUDE_ATTRIBUTE, type NodeToImageOptions, copyNodeAsPng, downloadNodeAsPng, nodeToPngBlob };
