import type { DetailGenerationMode } from "@/lib/detail-ui-protocol"; export const DETAIL_UI_DESIGN_SKILL_VERSION = "detail-ui-design-skill/v1"; export interface DetailUiDesignSkillSpec { version: typeof DETAIL_UI_DESIGN_SKILL_VERSION; name: string; source: string; language: "zh" | "en"; generationMode: DetailGenerationMode; canvas: { width: number; height: number; grid: string; maxOverlayCoverage: string; }; visualDirection: string[]; typography: string[]; layout: string[]; imageFusion: string[]; dslContract: string[]; antiPatterns: string[]; reviewChecklist: string[]; metadata: { screenCount: number; hasReferenceImages: boolean; hasModelImage: boolean; hasBundleImages: boolean; productName?: string; brandTone?: string; }; } export interface DetailUiDesignSkillSummary { version: typeof DETAIL_UI_DESIGN_SKILL_VERSION; name: string; source: string; visualDirection: string[]; reviewChecklist: string[]; } function normalizeText(value: unknown) { return String(value || "").replace(/\s+/g, " ").trim(); } export function buildDetailUiDesignSkillSpec(params: { language: "zh" | "en"; generationMode: DetailGenerationMode; screenCount: number; hasReferenceImages: boolean; hasModelImage: boolean; hasBundleImages: boolean; productName?: string; brandTone?: string; }): DetailUiDesignSkillSpec { const isZh = params.language === "zh"; return { version: DETAIL_UI_DESIGN_SKILL_VERSION, name: isZh ? "详情 UI 设计技能" : "Detail UI Design Skill", source: "Google Stitch DESIGN.md pattern + Apple product-showcase restraint + Linear precision + Figma editable-layer semantics", language: params.language, generationMode: params.generationMode, canvas: { width: 790, height: 1300, grid: isZh ? "8px 基础栅格,左右安全边距 56px,主内容按 12 栅格对齐" : "8px base grid, 56px side safe margins, main content aligned to a 12-column rhythm", maxOverlayCoverage: isZh ? "可编辑 UI 覆盖面积建议 18%-38%,最高不超过 45%" : "Editable UI overlay should cover 18%-38% of the canvas, never above 45%", }, visualDirection: isZh ? [ "产品/素材主体优先,主体轮廓不能被大面积 UI 卡片遮挡。", "一屏只建立一个主视觉焦点,文字层服务焦点,不把画面做成模板拼贴说明页。", "整体气质克制、精密、可上线:少装饰,靠比例、留白、对比和真实素材质感建立高级感。", "强调色只用于 CTA、重点徽章或关键对比,不能把整屏染成单一蓝紫渐变。", ] : [ "Prioritize the product or reference asset; never bury the silhouette under large UI cards.", "Create one dominant focal point per screen. Text supports the focal point instead of turning the frame into a collage.", "Use restrained production-grade polish: proportion, whitespace, contrast and material realism over decoration.", "Reserve accent color for CTA, proof badge, or key comparison only; avoid one-note blue/purple gradients.", ], typography: isZh ? [ "主标题 52-64px、字重 650-750、行高 1.06-1.15,禁止负字距,最多 2 行。", "副标题 26-34px、字重 550-650,必须是一句结果句,不写成长段说明。", "正文 18-24px、字重 450-600、行高 1.34-1.5,单块最多 4 行。", "同一套详情页只能使用一个字体家族和三个清晰层级:标题/副标题/正文。", ] : [ "Hero title 52-64px, weight 650-750, line-height 1.06-1.15, no negative tracking, max 2 lines.", "Subtitle 26-34px, weight 550-650, one result sentence only.", "Body 18-24px, weight 450-600, line-height 1.34-1.5, max 4 lines per block.", "Use one font family and exactly three readable levels: title, subtitle, body.", ], layout: isZh ? [ "首屏必须是封面海报/KV:单主体、强焦点、清晰标题安全区,禁止多卡片堆叠。", "卡片只用于承载真实信息模块;卡片圆角 8-12px,阴影轻,边框低透明。", "不要把卡片套卡片;一屏最多 1 个主面板 + 1 个辅助网格/证据条。", "UI 区域必须避开商品脸部、Logo、关键结构和手持/使用动作。", ] : [ "First screen must feel like a cover/KV poster: single subject, strong focus, clean headline safe zone.", "Use cards only for real information modules; radius 8-12px, light shadow, low-opacity border.", "No card nesting. Max one main panel plus one supporting grid/proof strip per screen.", "UI regions must avoid product face, logo, critical structure, and usage action.", ], imageFusion: isZh ? [ params.hasReferenceImages ? "已给参考图:生成画面必须复用参考素材的结构、颜色、材质、比例和关键识别特征。" : "未给参考图:画面主体仍需清晰、完整、可识别,不用抽象氛围图代替产品。", params.hasModelImage ? "已给模特图:涉及人物时保持同一人物身份,不替换脸型、发型、体型和服装风格。" : "未给模特图:不要依赖人物脸部作为主卖点。", params.hasBundleImages ? "搭配图只服务一屏关联销售,其余屏不要把搭配品抢成主角。" : "未给搭配图:不要凭空制造搭配商品主叙事。", "AGENT排版模式下,生图提示词只生成干净画面层,不生成任何可见文字、假按钮、假 UI。", ] : [ params.hasReferenceImages ? "Reference images are provided: preserve structure, color, material, proportion, and key identity cues." : "No reference image: keep the product subject clear and inspectable; avoid abstract atmosphere as a substitute.", params.hasModelImage ? "Model image is provided: preserve the same identity when humans appear." : "No model image: do not rely on a human face as the main selling point.", params.hasBundleImages ? "Bundle products serve exactly one cross-sell screen and must not steal the main subject elsewhere." : "No bundle refs: do not invent a bundle-product narrative.", "In agent-layout mode, image prompts generate clean background only: no visible text, fake buttons, or fake UI.", ], dslContract: isZh ? [ "dslV2Screens 必须语义化命名 id,例如 hero-title、proof-strip、feature-grid。", "region 使用 0-1 归一化坐标;宽高和位置必须像设计工具的 frame,而不是随意漂浮。", "nodes 只使用允许的 kind,优先 panel/stack/row/heading/body/badge/proof/cta 的少量组合。", "每个文本节点必须可编辑、短句化、层级明确,不把长说明塞进 heading。", ] : [ "dslV2Screens must use semantic ids such as hero-title, proof-strip, feature-grid.", "Use normalized 0-1 regions like design-tool frames, not arbitrary floating boxes.", "Use only allowed node kinds, with a sparse combination of panel/stack/row/heading/body/badge/proof/cta.", "Every text node must be editable, concise, and hierarchy-aware; no long explanations in headings.", ], antiPatterns: isZh ? [ "禁止大面积玻璃拟态卡片盖住主体。", "禁止蓝紫渐变、发光球、装饰块堆满画面。", "禁止主标题写“核心价值/场景痛点/第X屏/本屏展示”等规划话术。", "禁止同屏 4 个以上信息模块或超过 2 种强调色。", "禁止可见文字由生图模型生成,文字必须走可编辑 UI 层。", ] : [ "No large glassmorphism cards covering the subject.", "No blue/purple gradient wash, glowing blobs, or decorative block clutter.", "No planning phrases in visible copy such as Screen X or This frame shows.", "No more than 4 information modules or 2 accent colors in one screen.", "No image-model rendered visible text; text must live in editable UI layers.", ], reviewChecklist: isZh ? [ "主体是否完整、清晰、没有被 UI 遮挡?", "首屏是否像封面海报,而不是拼贴说明页?", "字体层级是否只有标题/副标题/正文三层,且统一?", "UI 覆盖面积是否控制在 45% 内,并避开关键素材?", "是否没有负字距、超大圆角、重阴影、卡片套卡片?", "visualPrompt 是否完全禁止生成可见文字?", ] : [ "Is the subject complete, clear, and unobstructed by UI?", "Does the first screen feel like a cover poster rather than a collage?", "Are there only title/subtitle/body levels, consistently applied?", "Is UI coverage under 45% and away from critical asset details?", "Are negative tracking, huge radii, heavy shadows, and nested cards avoided?", "Does visualPrompt fully forbid visible text generation?", ], metadata: { screenCount: Math.max(1, Math.round(params.screenCount || 1)), hasReferenceImages: params.hasReferenceImages, hasModelImage: params.hasModelImage, hasBundleImages: params.hasBundleImages, productName: normalizeText(params.productName) || undefined, brandTone: normalizeText(params.brandTone) || undefined, }, }; } export function summarizeDetailUiDesignSkill( spec: DetailUiDesignSkillSpec ): DetailUiDesignSkillSummary { return { version: spec.version, name: spec.name, source: spec.source, visualDirection: spec.visualDirection.slice(0, 4), reviewChecklist: spec.reviewChecklist.slice(0, 6), }; } export function buildDetailUiDesignSkillFlowStep( spec: DetailUiDesignSkillSpec ): string { return spec.language === "zh" ? "详情 UI Design Skill:按 DESIGN.md 方式锁定视觉语言、素材融合、安全区、可编辑 DSL 与反俗套自检。" : "Detail UI Design Skill: lock visual language, asset fusion, safe zones, editable DSL, and anti-slop review using DESIGN.md-style rules."; } export function buildDetailUiDesignSkillPrompt( spec: DetailUiDesignSkillSpec ): string { const section = (title: string, items: string[]) => `${title}\n${items.map((item) => `- ${item}`).join("\n")}`; const title = spec.language === "zh" ? `【${spec.name} ${spec.version}】` : `[${spec.name} ${spec.version}]`; return [ title, `${spec.language === "zh" ? "来源" : "Source"}: ${spec.source}`, `${spec.language === "zh" ? "画布" : "Canvas"}: ${spec.canvas.width}x${spec.canvas.height}; ${spec.canvas.grid}; ${spec.canvas.maxOverlayCoverage}`, section(spec.language === "zh" ? "视觉方向" : "Visual Direction", spec.visualDirection), section(spec.language === "zh" ? "字体层级" : "Typography", spec.typography), section(spec.language === "zh" ? "布局规则" : "Layout Rules", spec.layout), section(spec.language === "zh" ? "图片素材融合" : "Image Fusion", spec.imageFusion), section(spec.language === "zh" ? "DSL 输出契约" : "DSL Contract", spec.dslContract), section(spec.language === "zh" ? "禁止项" : "Anti-patterns", spec.antiPatterns), section(spec.language === "zh" ? "生成前自检" : "Preflight Checklist", spec.reviewChecklist), ].join("\n"); }