| 1 | export type LayoutIntent = |
| 2 | | 'cover' |
| 3 | | 'data-focus' |
| 4 | | 'comparison' |
| 5 | | 'timeline' |
| 6 | | 'concept' |
| 7 | | 'process' |
| 8 | | 'summary' |
| 9 | | 'quote' |
| 10 | | 'image-focus' |
| 11 | |
| 12 | export const LAYOUT_INTENTS = [ |
| 13 | 'cover', |
| 14 | 'data-focus', |
| 15 | 'comparison', |
| 16 | 'timeline', |
| 17 | 'concept', |
| 18 | 'process', |
| 19 | 'summary', |
| 20 | 'quote', |
| 21 | 'image-focus' |
| 22 | ] as const satisfies readonly LayoutIntent[] |
| 23 | |
| 24 | const LAYOUT_INTENT_SET = new Set<string>(LAYOUT_INTENTS) |
| 25 | |
| 26 | const LAYOUT_GUIDANCE: Record<LayoutIntent, string> = { |
| 27 | cover: 'Make the title or core message the visual focus.', |
| 28 | 'data-focus': 'Let metrics, charts, or quantitative evidence dominate the page.', |
| 29 | comparison: 'Use a structure that makes differences easy to compare.', |
| 30 | timeline: 'Use a phase, stage, roadmap, or progression structure.', |
| 31 | concept: 'Explain the idea with a clear visual hierarchy or central structure.', |
| 32 | process: 'Show steps, flow, mechanism, or cause-and-effect clearly.', |
| 33 | summary: 'Lead with the conclusion, then support it with compact evidence.', |
| 34 | quote: 'Make the statement the main visual anchor.', |
| 35 | 'image-focus': 'Let the visual material dominate, with text supporting it.' |
| 36 | } |
| 37 | |
| 38 | export const normalizeLayoutIntent = (value: unknown): LayoutIntent => { |
| 39 | const normalized = String(value ?? '') |
| 40 | .trim() |
| 41 | .toLowerCase() |
| 42 | .replace(/[_\s]+/g, '-') |
| 43 | return LAYOUT_INTENT_SET.has(normalized) ? (normalized as LayoutIntent) : 'concept' |
| 44 | } |
| 45 | |
| 46 | export const layoutIntentGuidance = (intent: LayoutIntent | undefined): string => |
| 47 | LAYOUT_GUIDANCE[normalizeLayoutIntent(intent)] |
| 48 | |
| 49 | export const formatLayoutIntentPrompt = (intent: LayoutIntent | undefined): string => |
| 50 | `Layout intent: ${normalizeLayoutIntent(intent)}.\nLayout guidance: ${layoutIntentGuidance(intent)}` |
| 51 |