/* [RFC-0104 + RFC-0118] Canonical SectionImageProps + ImageFade for the shared primitive. Image fades become a property of the image, not of the surrounding section. Parallax accepts boolean | number | object per RFC-0118 to align with RFC-0106 ParallaxVariant semantics. Do not introduce app-specific runtime composition or deployment behavior into this reusable package source file. RFC-0133: backfilled MODULE_MAP and CHANGE_SUMMARY markers for compass.validate compliance. */ import { z } from "zod"; import { livePhotoSchema } from "./live-photo.ts"; export const imageFadeSchema = z .object({ top: z.boolean().optional(), bottom: z.boolean().optional(), left: z.boolean().optional(), right: z.boolean().optional(), /** 0..0.5 — fade band width as a fraction of the image. Default 0.25. */ width: z.number().min(0).max(0.5).optional(), }) .strict(); export type ImageFade = z.infer; /** * RFC-0118: explicit parallax config. Mirrors RFC-0106 ParallaxVariant for * vocabulary consistency. */ export const sectionImageParallaxSchema = z .object({ variant: z.enum(["subtle", "balanced", "dramatic"]).optional(), /** 0..2; takes precedence over variant default. */ speed: z.number().min(0).max(2).optional(), respectReducedMotion: z.boolean().optional(), }) .strict(); export type SectionImageParallax = z.infer; /** * RFC-0118: section image parallax accepts three authoring forms: * - boolean — true is equivalent to { variant: "balanced" }; false disables. * - number — direct speed (0..2). * - object — { variant, speed, respectReducedMotion }. */ export const sectionImageParallaxPropSchema = z.union([ z.boolean(), z.number().min(0).max(2), sectionImageParallaxSchema, ]); export type SectionImageParallaxProp = z.infer; export const sectionImagePropsSchema = z .object({ /** Bare image name (RFC-0053). */ imageName: z.string().min(1), alt: z.string().min(1), fit: z.enum(["cover", "contain"]).optional(), quality: z.enum(["low", "mid", "high", "max"]).optional(), loading: z.enum(["eager", "lazy"]).optional(), aspectRatio: z.string().optional(), fade: imageFadeSchema.optional(), parallax: sectionImageParallaxPropSchema.optional(), /** RFC-0202: opt-in living photo — looping sibling `.webm` over this image. */ live: livePhotoSchema.optional(), lang: z.string().optional(), subPath: z.string().optional(), }) .strict(); export type SectionImageProps = z.infer;