| 1 | import type { AnimationPreferencesPayload } from '@shared/generation' |
| 2 | |
| 3 | const PREFERENCE_LINES: Record<string, string> = { |
| 4 | fade: '- Prefer data-anim="fade" for quiet text blocks, notes, and low-distraction entrances.', |
| 5 | 'fade-up': |
| 6 | '- Prefer data-anim="fade-up" as the standard entrance for cards, sections, and readable content groups.', |
| 7 | 'fade-down': |
| 8 | '- Prefer data-anim="fade-down" when content should enter from above, such as top labels or header-adjacent elements.', |
| 9 | 'fade-left': |
| 10 | '- Prefer data-anim="fade-left" when content should enter from the right side into position.', |
| 11 | 'fade-right': |
| 12 | '- Prefer data-anim="fade-right" when content should enter from the left side into position.', |
| 13 | 'scale-in': |
| 14 | '- Prefer data-anim="scale-in" for compact focal elements that should appear with a soft scale entrance.', |
| 15 | 'slide-up': |
| 16 | '- Prefer data-anim="slide-up" for stronger upward entrances when fade-up is too subtle.', |
| 17 | 'slide-down': |
| 18 | '- Prefer data-anim="slide-down" for stronger downward entrances when the visual flow starts near the top.', |
| 19 | 'slide-left': '- Prefer data-anim="slide-left" for stronger entrances from the right side.', |
| 20 | 'slide-right': '- Prefer data-anim="slide-right" for stronger entrances from the left side.', |
| 21 | 'fly-in': |
| 22 | '- Prefer data-anim="fly-in" only for directional emphasis; set data-anim-from to left, right, top, or bottom intentionally.', |
| 23 | wipe: |
| 24 | '- Prefer data-anim="wipe" for bars, timelines, progress strips, or section reveals; set data-anim-from intentionally.', |
| 25 | 'zoom-in': |
| 26 | '- Prefer data-anim="zoom-in" for a single dramatic focal number or key callout; avoid using it on many elements.', |
| 27 | 'spin-in': |
| 28 | '- Prefer data-anim="spin-in" only as a sparing playful entrance for one accent element.', |
| 29 | 'pulse-soft': |
| 30 | '- Prefer data-anim="pulse-soft" for very subtle attention on one KPI or key word.', |
| 31 | pulse: '- Prefer data-anim="pulse" for bounded emphasis on important metrics or callouts.', |
| 32 | 'pulse-strong': |
| 33 | '- Prefer data-anim="pulse-strong" only for urgent or high-priority callouts, at most one per slide.', |
| 34 | 'grow-shrink-soft': '- Prefer data-anim="grow-shrink-soft" for gentle emphasis that settles quickly.', |
| 35 | 'grow-shrink': |
| 36 | '- Prefer data-anim="grow-shrink" for important callouts that need more presence than pulse-soft.', |
| 37 | 'grow-shrink-strong': |
| 38 | '- Prefer data-anim="grow-shrink-strong" only for rare high-priority emphasis, at most one per slide.' |
| 39 | } |
| 40 | |
| 41 | export function formatAnimationPreferencesForPageWriting( |
| 42 | preferences: AnimationPreferencesPayload | null | undefined |
| 43 | ): string { |
| 44 | const ids = preferences?.ids || [] |
| 45 | const lines = ids.map((id) => PREFERENCE_LINES[id]).filter(Boolean) |
| 46 | if (lines.length === 0) return '' |
| 47 | |
| 48 | return [ |
| 49 | '## Animation preferences for page writing only', |
| 50 | '- Follow the oh-my-ppt-data-anim skill. Use exportable data-anim attributes on slide elements.', |
| 51 | '- Do not change slide outline, page count, slide titles, source facts, or content structure solely to satisfy animation.', |
| 52 | '- Animation is downstream only: follow the already-decided page form, content enrichment, source grounding, and layout density. Never reduce, skip, or reshape warranted content enrichment to satisfy an animation preference.', |
| 53 | '- Prefer subtle reading-order entrance animations.', |
| 54 | ...lines, |
| 55 | '- Avoid runtime-only attributes and custom anime timelines in normal editable/exportable pages.' |
| 56 | ].join('\n') |
| 57 | } |
| 58 |