import type { RenderedNodePath } from "./utils/nodeIdentity"; import type { ResponsiveTypography } from "./utils/responsivePresentation"; export interface SiteNode { /** Durable authored identity. Legacy nodes receive a deterministic path-hash id. */ id?: string; /** Structured DOM-instance identity; serialized to data-node-id only in editable render mode. */ renderedIdPath?: RenderedNodePath; type: string; props: Record; children?: SiteNode[]; } export interface EditableNodeAttributes { "data-node-id"?: string; } export interface ButtonPresentationProps { variant?: "primary" | "secondary" | "outline" | "ghost" | "accent"; size?: "xs" | "sm" | "md" | "lg"; fullWidth?: boolean; fontSize?: string; responsiveTypography?: ResponsiveTypography; fontWeight?: number; lineHeight?: string; letterSpacing?: string; paddingX?: string; paddingY?: string; borderWidth?: "none" | "sm" | "md" | "lg"; outlineWidth?: "none" | "sm" | "md" | "lg"; shadow?: "none" | "subtle" | "sm" | "md" | "lg"; } export interface NavItemPresentation { label: string; placement?: "primary" | "utility"; visibility?: "all" | "desktop" | "mobile"; } export interface NavLink extends ButtonPresentationProps, NavItemPresentation { to: string; type?: "link" | "button"; openInNewTab?: boolean; downloadAsset?: { src: string; displayFilename?: string; asset?: string; } | null; downloadFilename?: string; } export interface NavDropdown extends NavItemPresentation { type: "dropdown"; items: NavLink[]; } export type NavItem = NavLink | NavDropdown; export interface FooterColumn { title: string; links: NavLink[]; } export interface PageMeta { title?: string; description?: string; image?: string; canonical?: string; } export interface PageSeoRobots { index?: boolean; follow?: boolean; sitemap?: boolean; noindex?: boolean; nofollow?: boolean; } /** Resolved per-route SEO metadata preserved on a materialized SitePage. */ export interface PageSeo { title?: string; description?: string; image?: string; socialTitle?: string; socialDescription?: string; socialImage?: string; /** Back-compatible authored aliases accepted by the compiler. */ social_title?: string; social_description?: string; social_image?: string; ogTitle?: string; ogDescription?: string; ogImage?: string; canonical?: string; schemaType?: string; schema_type?: string; structuredData?: Record; structured_data?: Record; jsonLd?: Record; json_ld?: Record; robots?: PageSeoRobots; index?: boolean; follow?: boolean; sitemap?: boolean; noindex?: boolean; nofollow?: boolean; changefreq?: string; priority?: number; routeId?: string; route_id?: string; routeType?: string; route_type?: string; propertyId?: string | number; property_id?: string | number; } export interface SitePage { path: string; tree: SiteNode; /** Concrete property owning a compile-time materialized property page. */ propertyId?: string; /** Per-page meta overrides for SEO (title, description, og:image) */ meta?: PageMeta; /** Canonical resolved SEO, social, robots, and supplemental JSON-LD fields. */ seo?: PageSeo; /** Layout name from site.layouts — wraps page tree in shared Nav/Footer/Modals */ layout?: string; } export interface SiteLayout { tree: SiteNode; } export interface SiteMeta { title: string; description?: string; image?: string; url?: string; } /** A theme token value: a concrete string or an alias to another token. */ export type ThemeTokenValue = string | { $token: string; }; export interface FontFace { src: string; weight: string; style: string; unicodeRange?: string; } export interface FontFallbackMetrics { localFallback: string; sizeAdjust: string; ascentOverride: string; descentOverride: string; lineGapOverride: string; } export interface FontFamilyDef { id: string; name: string; source: "custom" | "google"; faces: FontFace[]; fallback?: string; metrics?: FontFallbackMetrics; } export interface SiteTheme { /** Legacy flat color block — still accepted for back-compat. */ colors?: { background: string; foreground: string; primary: string; secondary: string; accent: string; muted: string; }; /** Font pair: "modern" (Inter), "editorial" (Playfair+Source Sans), "clean" (DM Sans), "bold" (Space Grotesk+Nunito) or custom {heading, body} */ fonts?: { heading: string; body: string; } | "modern" | "editorial" | "clean" | "bold"; /** Self-hosted font definitions snapshotted with the site for reproducible rendering. */ fontFamilies?: FontFamilyDef[]; /** Border radius scale: "none" | "sm" | "md" | "lg" | "xl" | "full" */ radius?: "none" | "sm" | "md" | "lg" | "xl" | "full"; /** Shadow style: "none" | "crisp" | "soft" | "heavy" */ shadow?: "none" | "crisp" | "soft" | "heavy"; /** * Token model: dotted token names (e.g. "color.primary" or * "font.heading.line-height") → CSS value or {$token} alias. */ tokens?: Record; /** Per-mode token overrides, keyed by mode (e.g. "building:123"). */ modes?: Record>; } export interface SiteProperty { propertyId: string; apiBaseUrl?: string; } export interface AnalyticsConfig { /** Explicit tag destination. Omitted preserves legacy dual-ID behavior. */ mode?: "none" | "ga4" | "gtm"; /** Google Analytics 4 measurement ID (e.g. "G-XXXXXX") */ ga4?: string; /** Google Tag Manager container ID (e.g. "GTM-XXXXXX") */ gtm?: string; /** Google Consent Mode v2 defaults and the first-party choice banner. */ consent?: { banner?: { enabled?: boolean; privacyPolicyUrl?: string; }; defaults?: { analytics_storage?: "denied" | "granted"; ad_storage?: "denied" | "granted"; ad_user_data?: "denied" | "granted"; ad_personalization?: "denied" | "granted"; }; }; } export interface SiteConfig { meta: SiteMeta; theme?: SiteTheme; siteId?: string; /** Resolved property-id to authored route slug mapping for multi-property links. */ buildingSlugs?: Record; property?: SiteProperty; /** Skip session-token auth; use devApiToken for API calls instead. */ devMode?: boolean; /** Static Bearer token used when devMode is true (e.g. a vendor API key). */ devApiToken?: string; /** Named layouts for DRY templates — each layout has a component tree with Slot placeholders */ layouts?: Record; /** Analytics tracking configuration */ analytics?: AnalyticsConfig; pages: SitePage[]; } //# sourceMappingURL=types.d.ts.map