export type BackgroundType = "color" | "video" | "image"; export interface BoothTheme { backgroundType: BackgroundType; backgroundColor: string; backgroundVideoUrl?: string; backgroundImageUrl?: string; primaryColor: string; accentColor: string; surfaceColor: string; textColor: string; logoUrl: string; logoWidth?: number; } export interface CameraConfig { defaultFacingMode: "user" | "environment"; aspectRatio: "9:16" | "3:4" | "1:1" | "4:3"; countdownSeconds: number; allowUpload: boolean; maxUploadSizeMb: number; } export interface FeatureFlags { showQrCode: boolean; showDownloadButton: boolean; showPrintButton: boolean; showRetakeButton: boolean; showInstagramShare?: boolean; } export interface RateLimitsConfig { maxGenerationsPerDevice: number; // 0 = unlimited cooldownMinutes: number; } export interface AIProviderConfig { provider: "gemini" | "openrouter"; model: string; timeoutMs: number; } export interface AIConfig { primary: AIProviderConfig; backup: AIProviderConfig; cooldownDurationMinutes: number; enableSfwCheck: boolean; } export interface KioskConfig { enableAutoReset: boolean; idleTimeoutSeconds: number; } export interface LocalizedString { en: string; zh: string; } export interface BoothLabels { welcomeBadge: LocalizedString; welcomeTitle: LocalizedString; welcomeSubtitle: LocalizedString; welcomeDesc: LocalizedString; welcomeCta: LocalizedString; cameraInstruction: LocalizedString; cameraSnap: LocalizedString; cameraUpload: LocalizedString; confirmTitle: LocalizedString; retakeButton: LocalizedString; confirmButton: LocalizedString; styleSelectionTitle: LocalizedString; styleSelectionSubtitle: LocalizedString; confirmStyleButton: LocalizedString; backButton: LocalizedString; processingTitle: LocalizedString; processingSubtitle: LocalizedString; resultTitle: LocalizedString; scanQrLabel: LocalizedString; downloadLabel: LocalizedString; wechatSaveTip: LocalizedString; printLabel: LocalizedString; startOverLabel: LocalizedString; instagramShareLabel?: LocalizedString; } export interface BoothConfig { appName: string; kioskMode: boolean; theme: BoothTheme; camera: CameraConfig; features: FeatureFlags; limits: RateLimitsConfig; ai: AIConfig; kiosk: KioskConfig; labels: BoothLabels; } export interface BoothStyle { id: string; name: LocalizedString | string; description?: LocalizedString | string; thumbnail: string; sampleResult?: string; prompt: string; negativePrompt?: string; } export type ScreenState = | "standby" | "camera" | "confirm" | "style" | "processing" | "result" | "rate_limited";