/* [RFC-0104] Canonical CtaConfig and CtaGroupConfig — one structured shape used by every section that renders a call-to-action. Replaces the four ad-hoc CTA shapes that lived on hero / final-cta / hero-decision-card / notausgang-block. 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. RFC-1257: structured CtaTarget + scenario-plumbed contact links */ import { z } from "zod"; import { horizontalAlignSchema } from "./horizontal-align.ts"; import { vendorIconConfigSchema } from "./standard-list-item.ts"; import { TARGET_QUERY_KEY_PATTERN, TARGET_QUERY_VALUE_PATTERN } from "../referral/patterns.ts"; export const ctaVariantSchema = z.enum(["primary", "secondary", "ghost", "danger"]); export type CtaVariant = z.infer; export const ctaSizeSchema = z.enum(["sm", "md", "lg"]); export type CtaSize = z.infer; export const ctaIconPositionSchema = z.enum(["leading", "trailing"]); export type CtaIconPosition = z.infer; export const ctaTargetSchema = z.discriminatedUnion("kind", [ z .object({ kind: z.literal("internal"), pageId: z.string().min(1), // RFC-1257: bounded query map — emitted as path?k=v before #anchor. query: z .record( z.string().regex(TARGET_QUERY_KEY_PATTERN), z.string().regex(TARGET_QUERY_VALUE_PATTERN), ) .optional(), anchor: z.string().optional(), }) .strict(), z .object({ kind: z.literal("external"), href: z.string().min(1), rel: z.string().optional(), }) .strict(), z .object({ kind: z.literal("anchor"), anchor: z.string().min(1), }) .strict(), ]); export type CtaTarget = z.infer; export const ctaConfigSchema = z .object({ label: z.string().min(1), target: ctaTargetSchema, ariaLabel: z.string().optional(), variant: ctaVariantSchema.optional(), icon: vendorIconConfigSchema.optional(), iconPosition: ctaIconPositionSchema.optional(), size: ctaSizeSchema.optional(), fullWidth: z.boolean().optional(), }) .strict(); export type CtaConfig = z.infer; export const ctaGroupConfigSchema = z .object({ align: horizontalAlignSchema.optional(), items: z.array(ctaConfigSchema).min(1), }) .strict(); export type CtaGroupConfig = z.infer;