/**
 * Page Generator: an extension's landing / homepage as ONE static HTML file.
 *
 * No JavaScript in the output — pure HTML/CSS, so it deploys anywhere
 * (GitHub Pages, Netlify, S3) and trivially passes CSP. Store CTAs render
 * only for the stores the developer actually filled in.
 *
 * Every user-supplied string is HTML-escaped, every link is scheme-clamped
 * (safeHref: http(s) only; the support link may also be a single mailto:
 * address) and every image source is clamped to https, a
 * relative path or a raster `data:image/…;base64` URL (safeImageSrc). An
 * inline SVG logo is validated (landingLogoSvgProblem) and then embedded
 * through `<img src="data:image/svg+xml,…">`, where browsers never run
 * scripts or fetch external resources — so even a validator miss cannot
 * script the page.
 *
 * SINGLE SOURCE, THREE COPIES:
 *   shared-types/landing-page.ts            (canonical — edit here; dojo re-exports it)
 *   tools/extenshi-mcp/src/landing-page.ts  (copy for the published @extenshi/mcp)
 *   tools/extenshi-cli/src/landing-page.ts  (copy for the published @extenshi/cli)
 * The published packages cannot import workspace shared-types at runtime.
 * The copies differ from this file ONLY in the import specifiers
 * (`./json-ld.js` there, the package specifier here — see
 * module-specifiers.test.ts for why shared-types may not use relative ones).
 * Schema v2 (sections, theme tokens, locales, SEO) lives in
 * landing-sections.ts, copied the same way; `renderLandingForm` there is the
 * entry point that dispatches v1 forms to buildLandingPage below.
 * `landing-page-sync.test.ts` in both packages fails when a copy drifts.
 * After editing, run:
 *   sed "s#from 'shared-types\/#from './#" shared-types/landing-page.ts > tools/extenshi-mcp/src/landing-page.ts
 *   sed "s#from 'shared-types\/#from './#" shared-types/landing-page.ts > tools/extenshi-cli/src/landing-page.ts
 */
import type { LandingV2Fields } from './landing-sections.js';
export type LandingBrowser = 'chrome' | 'firefox' | 'edge';
export interface LandingFeature {
    title: string;
    description: string;
}
export interface LandingScreenshot {
    /** https URL, or a path relative to the page (e.g. `screenshots/popup.png`). */
    url: string;
    alt: string;
}
/**
 * Serializable form persisted as `page-generator` tool state (`{ form }`).
 * The optional fields were added later; rows saved before them still hydrate.
 * The v2 fields (sections, tokens, seo, locales — landing-sections.ts) are read
 * only when `schemaVersion` is 2; buildLandingPage below never looks at them.
 */
export interface LandingForm extends LandingV2Fields {
    extensionName: string;
    tagline: string;
    description: string;
    accentColor: string;
    theme: 'light' | 'dark';
    chromeUrl: string;
    firefoxUrl: string;
    edgeUrl: string;
    privacyPolicyUrl: string;
    supportUrl: string;
    features: LandingFeature[];
    /** Public https URL the page will live at: canonical link, og:url, JSON-LD url. */
    homepageUrl?: string;
    /** Logo image: https URL, relative path, or `data:image/(png|jpeg|gif|webp);base64,…`. */
    logoUrl?: string;
    /** Inline SVG logo source; wins over logoUrl when it passes validation. */
    logoSvg?: string;
    screenshots?: LandingScreenshot[];
}
/** Input limits shared by the MCP tool and CLI schemas. */
export declare const LANDING_LIMITS: {
    readonly extensionName: 120;
    readonly tagline: 200;
    readonly description: 2000;
    readonly url: 2000;
    readonly features: 12;
    readonly featureTitle: 120;
    readonly featureDescription: 500;
    readonly screenshots: 8;
    readonly screenshotAlt: 200;
    readonly logoSvgBytes: 100000;
    readonly logoUrl: 400000;
};
export declare const DEFAULT_LANDING_FORM: LandingForm;
export interface LandingPageInput {
    extensionName: string;
    tagline: string;
    description: string;
    accentColor: string;
    theme: 'light' | 'dark';
    storeUrls: Partial<Record<LandingBrowser, string>>;
    features: LandingFeature[];
    privacyPolicyUrl: string;
    supportUrl: string;
    /**
     * Optional inline SVG logo. Validated with landingLogoSvgProblem() and
     * embedded as an `<img>` data URI; a rejected SVG falls back to logoUrl,
     * then to a monogram.
     */
    logoSvg?: string;
    logoUrl?: string;
    homepageUrl?: string;
    screenshots?: LandingScreenshot[];
}
/**
 * Rebuild the editor form from a saved `page-generator` row (or the project
 * name when nothing is saved). Called during render — not in an effect —
 * so the live preview iframe mounts with this payload, not the empty default.
 * An older row that predates `features` (or the optional fields) still yields
 * a full form.
 */
export declare function hydrateLandingForm(saved: {
    form?: Partial<LandingForm>;
} | null | undefined, projectName?: string | null): LandingForm;
export declare function landingFormToInput(form: LandingForm, logoSvg?: string): LandingPageInput;
/** Tolerates non-strings from hand-edited JSON or an old saved row. */
export declare function str(v: unknown): string;
export declare function esc(s: string): string;
export declare function safeHref(raw: string): string;
/** safeHref() for the support link only: http(s), or a validated mailto: address. */
export declare function safeSupportHref(raw: string): string;
/** Image src clamp: https, relative path, or raster data URI; '' when unsafe. */
export declare function safeImageSrc(raw: unknown): string;
export declare function canonicalUrl(raw: unknown): string;
/** Absolute https form of an image URL (for og:image / JSON-LD), or ''. */
export declare function absoluteImageUrl(raw: unknown, base: string): string;
/**
 * Why an inline SVG logo is refused, or null when it is acceptable. A refusal
 * never throws: buildLandingPage falls back to logoUrl / the monogram, and the
 * MCP tool and CLI surface the reason instead of silently dropping the logo.
 */
export declare function landingLogoSvgProblem(svg: string): string | null;
export declare const HEX_COLOR: RegExp;
/**
 * Human-readable notes about input the page silently corrected (a link clamped
 * to "#", an unsafe image dropped, a refused logo). Same rules as the builder,
 * so agents and the CLI can report exactly what did not make it into the page.
 */
export declare function landingPageWarnings(input: LandingPageInput): string[];
export declare function buildLandingPage(input: LandingPageInput): string;
//# sourceMappingURL=landing-page.d.ts.map