export type BrandingFormValues = { primary: string; accent: string; background: string; surface: string; headingFont: string; bodyFont: string; logoDataUrl: string; mode: 'light' | 'dark' | 'auto'; }; export type BrandingFormDefaults = Pick; type BrandingRecord = Record; const isRecord = (value: unknown): value is BrandingRecord => Boolean(value) && typeof value === 'object' && !Array.isArray(value); const readHexColor = (value: unknown, fallback: string): string => { if (typeof value === 'string' && value.trim().startsWith('#')) { return value.trim(); } return fallback; }; export function extractBrandingForm(settings: unknown, defaults: BrandingFormDefaults): BrandingFormValues { const settingsRecord = isRecord(settings) ? settings : {}; const branding = isRecord(settingsRecord.branding) ? (settingsRecord.branding as BrandingRecord) : settingsRecord; const palette = isRecord(branding.palette) ? (branding.palette as BrandingRecord) : {}; const typography = isRecord(branding.typography) ? (branding.typography as BrandingRecord) : {}; const primary = readHexColor(palette.primary, readHexColor(branding.primary_color, defaults.primary)); const accent = readHexColor( palette.secondary, readHexColor(branding.secondary_color, readHexColor(branding.accent_color, defaults.accent)) ); const background = readHexColor(palette.background, readHexColor(branding.background_color, defaults.background)); const surface = readHexColor(palette.surface, readHexColor(branding.surface_color, background)); const headingFont = typeof typography.heading === 'string' ? typography.heading : (branding.heading_font as string | undefined); const bodyFont = typeof typography.body === 'string' ? typography.body : (branding.body_font as string | undefined); const mode = branding.mode === 'light' || branding.mode === 'dark' || branding.mode === 'auto' ? branding.mode : defaults.mode; return { primary, accent, background, surface, headingFont: headingFont ?? '', bodyFont: bodyFont ?? '', logoDataUrl: typeof branding.logo_data_url === 'string' ? branding.logo_data_url : '', mode, }; }