File size: 19,334 Bytes
f201243
 
 
 
 
 
 
 
 
 
 
 
26e8ad9
 
 
f201243
 
 
 
 
 
 
 
 
 
 
26e8ad9
 
f201243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26e8ad9
 
f201243
 
 
 
 
 
 
 
 
26e8ad9
 
 
 
f201243
26e8ad9
 
 
 
 
f201243
 
26e8ad9
f201243
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
"""
Affiliate Marketing Concepts Framework (Lite Version)
100 concepts organized into 10 categories.
Concepts answer: "How do I show it visually?" (Creative HOW)
"""

from typing import Dict, List, Any, Optional
from enum import Enum
import random


class ConceptCategory(str, Enum):
    """Concept categories - focused on creative HOW (storytelling, proof, etc.)
    Note: Visual layouts (before/after, split screen, etc.) are now in visuals.py
    """
    UGC_NATIVE = "ugc_native"
    STORYTELLING = "storytelling"
    COMPARISON = "comparison"
    AUTHORITY = "authority"
    SOCIAL_PROOF = "social_proof"
    SCROLL_STOPPING = "scroll_stopping"
    EDUCATIONAL = "educational"
    PERSONALIZATION = "personalization"
    CTA_FOCUSED = "cta_focused"


# Complete concepts framework - focused on creative HOW (not visual layouts)
# Note: Visual structure layouts (before/after, split screen, etc.) moved to visuals.py
CONCEPTS = {
    ConceptCategory.UGC_NATIVE: {
        "name": "UGC & Native",
        "concepts": [
            {"key": "selfie_style", "name": "Selfie-Style Image", "structure": "Phone camera angle", "visual": "Casual, authentic feel"},
            {"key": "casual_phone", "name": "Casual Phone Shot", "structure": "Mobile perspective", "visual": "Unpolished, authentic"},
            {"key": "pov", "name": "POV Perspective", "structure": "First-person view", "visual": "Immersive feel"},
            {"key": "just_found", "name": "Just Found This", "structure": "Discovery moment", "visual": "Excited, sharing"},
            {"key": "organic_feed", "name": "Organic Feed Style", "structure": "Native to platform", "visual": "Doesn't look like ad"},
            {"key": "influencer", "name": "Influencer-Style", "structure": "Polished but authentic", "visual": "Influencer aesthetic"},
            {"key": "low_production", "name": "Low-Production Authentic", "structure": "Raw, unpolished", "visual": "Authentic feel"},
            {"key": "reaction", "name": "Reaction Shot", "structure": "Emotional reaction", "visual": "Clear emotion visible"},
            {"key": "screenshot", "name": "Screenshot-Style", "structure": "Device screenshot", "visual": "Realistic screenshot"},
            {"key": "story_frame", "name": "Story Frame", "structure": "Vertical story format", "visual": "Story-style layout"},
            {"key": "behind_scenes", "name": "Behind the Scenes", "structure": "Raw, unedited look", "visual": "Authentic, unpolished"},
            {"key": "day_in_life", "name": "Day in the Life", "structure": "Daily routine snapshot", "visual": "Relatable daily moments"},
            {"key": "unboxing_style", "name": "Unboxing Style", "structure": "Product reveal moment", "visual": "Discovery excitement"},
        ]
    },
    ConceptCategory.STORYTELLING: {
        "name": "Storytelling",
        "concepts": [
            {"key": "emotional_snapshot", "name": "Emotional Snapshot", "structure": "Single emotional moment", "visual": "Authentic expression"},
            {"key": "relatable_moment", "name": "Relatable Daily Moment", "structure": "Everyday scene", "visual": "Relatable situation"},
            {"key": "micro_story", "name": "Micro-Story Scene", "structure": "Small story moment", "visual": "Narrative feel"},
            {"key": "life_situation", "name": "Life Situation", "structure": "Real-life context", "visual": "Authentic situation"},
            {"key": "decision_moment", "name": "Decision Moment", "structure": "Decision point", "visual": "Contemplative"},
            {"key": "problem_awareness", "name": "Problem Awareness Scene", "structure": "Problem visible", "visual": "Awareness moment"},
            {"key": "turning_point", "name": "Turning Point Frame", "structure": "Transformation moment", "visual": "Change visible"},
            {"key": "relief_moment", "name": "Relief Moment", "structure": "Relief visible", "visual": "Peace visible"},
            {"key": "success_moment", "name": "Success Moment", "structure": "Success visible", "visual": "Achievement visible"},
            {"key": "future_projection", "name": "Future Projection", "structure": "Future vision", "visual": "Aspirational"},
            {"key": "journey_arc", "name": "Journey Arc", "structure": "Complete transformation story", "visual": "Full journey visible"},
            {"key": "milestone_moment", "name": "Milestone Moment", "structure": "Key achievement moment", "visual": "Celebration visible"},
        ]
    },
    ConceptCategory.COMPARISON: {
        "name": "Comparison & Logic",
        "concepts": [
            {"key": "side_by_side_table", "name": "Side-by-Side Table", "structure": "Comparison table", "visual": "Checkmarks/crosses"},
            {"key": "old_vs_new", "name": "Old Way vs New Way", "structure": "Old vs new comparison", "visual": "Modern highlighted"},
            {"key": "choice_elimination", "name": "Choice Elimination", "structure": "Others crossed out", "visual": "Winner clear"},
            {"key": "feature_breakdown", "name": "Feature Breakdown", "structure": "Features compared", "visual": "Easy to compare"},
            {"key": "pros_cons", "name": "Pros vs Cons", "structure": "Pros on one side, cons other", "visual": "Balanced view"},
            {"key": "ranking", "name": "Ranking Visual", "structure": "Ranked list", "visual": "Top highlighted"},
            {"key": "winner_highlight", "name": "Winner Highlight", "structure": "Winner highlighted", "visual": "Others dimmed"},
            {"key": "bar_scale", "name": "Bar / Scale Visual", "structure": "Visual bars/scales", "visual": "Easy to compare"},
            {"key": "price_stack", "name": "Price Stack", "structure": "Prices stacked", "visual": "Savings visible"},
            {"key": "value_breakdown", "name": "Value Breakdown", "structure": "Value components", "visual": "Easy to understand"},
            {"key": "versus_comparison", "name": "Versus Comparison", "structure": "Head-to-head comparison", "visual": "Clear winner"},
            {"key": "feature_matrix", "name": "Feature Matrix", "structure": "Feature comparison grid", "visual": "Easy comparison"},
        ]
    },
    ConceptCategory.AUTHORITY: {
        "name": "Authority & Trust",
        "concepts": [
            {"key": "expert_portrait", "name": "Expert Portrait", "structure": "Professional portrait", "visual": "Trustworthy appearance"},
            {"key": "badge_seal", "name": "Badge / Seal Visual", "structure": "Badges prominent", "visual": "Official look"},
            {"key": "certification", "name": "Certification Overlay", "structure": "Cert overlaid", "visual": "Official"},
            {"key": "media_mention", "name": "Media Mention Style", "structure": "Media logos/quotes", "visual": "Credible"},
            {"key": "professional_setting", "name": "Professional Setting", "structure": "Office/professional space", "visual": "Clean, organized"},
            {"key": "office_scene", "name": "Office / Desk Scene", "structure": "Office environment", "visual": "Professional"},
            {"key": "institutional", "name": "Institutional Look", "structure": "Official design", "visual": "Institutional"},
            {"key": "data_backed", "name": "Data-Backed Visual", "structure": "Charts, graphs", "visual": "Data visible"},
            {"key": "chart_graph", "name": "Chart / Graph Snapshot", "structure": "Chart dominates", "visual": "Easy to read"},
            {"key": "trust_signals", "name": "Trust Signal Stack", "structure": "Multiple trust elements", "visual": "Organized signals"},
            {"key": "credentials_display", "name": "Credentials Display", "structure": "Certifications shown", "visual": "Official credentials"},
            {"key": "partnership_logos", "name": "Partnership Logos", "structure": "Partner brands visible", "visual": "Trusted partnerships"},
        ]
    },
    ConceptCategory.SOCIAL_PROOF: {
        "name": "Social Proof",
        "concepts": [
            {"key": "testimonial_screenshot", "name": "Testimonial Screenshot", "structure": "Screenshot format", "visual": "Authentic testimonial"},
            {"key": "quote_card", "name": "Quote Card", "structure": "Quote as main visual", "visual": "Clear, readable"},
            {"key": "case_study_frame", "name": "Case Study Frame", "structure": "Case study format", "visual": "Results visible"},
            {"key": "crowd", "name": "Crowd Visual", "structure": "Many people visible", "visual": "Popular feel"},
            {"key": "others_like_you", "name": "Others Like You", "structure": "Similar people", "visual": "Relatable, authentic"},
            {"key": "real_customer", "name": "Real Customer Photo", "structure": "Real customer shown", "visual": "Authentic, relatable"},
            {"key": "comment_screenshot", "name": "Comment Screenshot", "structure": "Comments visible", "visual": "Realistic comments"},
            {"key": "ugc_collage", "name": "UGC Collage", "structure": "Multiple UGC pieces", "visual": "Collage format"},
            {"key": "community", "name": "Community Visual", "structure": "Community visible", "visual": "Belonging feel"},
            {"key": "user_spotlight", "name": "User Spotlight", "structure": "Individual user featured", "visual": "Personal success story"},
            {"key": "group_success", "name": "Group Success", "structure": "Multiple success stories", "visual": "Collective achievement"},
        ]
    },
    ConceptCategory.SCROLL_STOPPING: {
        "name": "Scroll-Stopping",
        "concepts": [
            {"key": "shock_headline", "name": "Shock Headline", "structure": "Shocking headline dominates", "visual": "Bold, high contrast"},
            {"key": "unusual_contrast", "name": "Unusual Contrast", "structure": "High contrast, unusual colors", "visual": "Stands out"},
            {"key": "pattern_break", "name": "Pattern Break Design", "structure": "Different from expected", "visual": "Unexpected"},
            {"key": "unexpected_image", "name": "Unexpected Image", "structure": "Surprising visual", "visual": "Attention-grabbing"},
            {"key": "bold_claim", "name": "Bold Claim Card", "structure": "Bold claim prominent", "visual": "Large text"},
            {"key": "glitch_highlight", "name": "Glitch / Highlight", "structure": "Glitch effect", "visual": "Modern"},
            {"key": "disruptive_color", "name": "Disruptive Color Use", "structure": "Unexpected colors", "visual": "Disruptive"},
            {"key": "meme_style", "name": "Meme-Style Image", "structure": "Meme format", "visual": "Shareable"},
            {"key": "visual_tension", "name": "Visual Tension", "structure": "Tension in visual", "visual": "Engaging"},
            {"key": "bold_typography", "name": "Bold Typography Focus", "structure": "Typography dominates", "visual": "Text-first impact"},
            {"key": "motion_blur", "name": "Motion Blur Effect", "structure": "Dynamic movement feel", "visual": "Energy and action"},
        ]
    },
    ConceptCategory.EDUCATIONAL: {
        "name": "Educational & Explainer",
        "concepts": [
            {"key": "how_it_works", "name": "How It Works", "structure": "Process explanation", "visual": "Step-by-step"},
            {"key": "three_step", "name": "3-Step Process", "structure": "Step 1→2→3", "visual": "Simple flow"},
            {"key": "flow_diagram", "name": "Flow Diagram", "structure": "Flowchart format", "visual": "Easy to follow"},
            {"key": "simple_explainer", "name": "Simple Explainer", "structure": "Simple explanation", "visual": "Easy to understand"},
            {"key": "faq", "name": "FAQ Visual", "structure": "FAQ format", "visual": "Clear Q&A"},
            {"key": "mistake_callout", "name": "Mistake Callout", "structure": "Mistakes highlighted", "visual": "Avoid them"},
            {"key": "do_dont", "name": "Do / Don't Visual", "structure": "Do vs Don't", "visual": "Easy to understand"},
            {"key": "learning_card", "name": "Learning Card", "structure": "Card with content", "visual": "Educational"},
            {"key": "visual_guide", "name": "Visual Guide", "structure": "Guide format", "visual": "Instructional"},
            {"key": "instructional", "name": "Instructional Frame", "structure": "Instruction format", "visual": "Easy to follow"},
            {"key": "tip_card", "name": "Tip Card", "structure": "Quick tip format", "visual": "Actionable advice"},
            {"key": "checklist_visual", "name": "Checklist Visual", "structure": "Checklist format", "visual": "Easy to follow"},
        ]
    },
    ConceptCategory.PERSONALIZATION: {
        "name": "Call-Out & Personalization",
        "concepts": [
            {"key": "if_you_are", "name": "If You Are X…", "structure": "Direct callout", "visual": "Specific group"},
            {"key": "age_specific", "name": "Age-Specific Visual", "structure": "Age-specific imagery", "visual": "Relatable"},
            {"key": "location_specific", "name": "Location-Specific", "structure": "Location visible", "visual": "Local feel"},
            {"key": "role_based", "name": "Role-Based Scene", "structure": "Role-specific scene", "visual": "Relatable"},
            {"key": "lifestyle_scene", "name": "Lifestyle Match", "structure": "Lifestyle visible", "visual": "Match"},
            {"key": "identity_mirror", "name": "Identity Mirror", "structure": "Identity reflected", "visual": "Connection"},
            {"key": "targeted_headline", "name": "Targeted Headline", "structure": "Targeted headline", "visual": "Relevant"},
            {"key": "personalized_hook", "name": "Personalized Hook", "structure": "Personalized opening", "visual": "Connection"},
            {"key": "segment_callout", "name": "Segment Callout", "structure": "Segment-specific", "visual": "Targeted"},
            {"key": "direct_address", "name": "Direct Address", "structure": "Direct address format", "visual": "Personal"},
            {"key": "custom_message", "name": "Custom Message", "structure": "Personalized message", "visual": "One-on-one feel"},
            {"key": "targeted_audience", "name": "Targeted Audience Visual", "structure": "Specific audience shown", "visual": "Relatable group"},
        ]
    },
    ConceptCategory.CTA_FOCUSED: {
        "name": "CTA-Focused",
        "concepts": [
            {"key": "button_focused", "name": "Button-Focused Image", "structure": "Button prominent", "visual": "Action-oriented"},
            {"key": "arrow_flow", "name": "Arrow-Directed Flow", "structure": "Arrows point to CTA", "visual": "Directional"},
            {"key": "highlighted_cta", "name": "Highlighted CTA Box", "structure": "CTA box stands out", "visual": "Clear"},
            {"key": "action_words", "name": "Action Words Overlay", "structure": "Action words prominent", "visual": "Urgent"},
            {"key": "click_prompt", "name": "Click Prompt Visual", "structure": "Click prompt visible", "visual": "Action-oriented"},
            {"key": "tap_here", "name": "Tap-Here Cue", "structure": "Tap here visible", "visual": "Mobile-friendly"},
            {"key": "next_step", "name": "Next Step Highlight", "structure": "Next step prominent", "visual": "Action-oriented"},
            {"key": "simple_cta", "name": "Simple CTA Card", "structure": "Simple card with CTA", "visual": "Minimal"},
            {"key": "countdown_cta", "name": "Countdown CTA", "structure": "Countdown + CTA", "visual": "Urgent"},
            {"key": "final_push", "name": "Final Push Frame", "structure": "Final push format", "visual": "Urgent, action"},
            {"key": "pulsing_cta", "name": "Pulsing CTA", "structure": "Animated attention", "visual": "Eye-catching action"},
            {"key": "multi_cta", "name": "Multiple CTAs", "structure": "Multiple action options", "visual": "Flexible engagement"},
        ]
    },
}


def get_all_concepts() -> List[Dict[str, Any]]:
    """Get all concepts as a flat list."""
    all_concepts = []
    for category, data in CONCEPTS.items():
        for concept in data["concepts"]:
            concept_copy = concept.copy()
            concept_copy["category"] = data["name"]
            concept_copy["category_key"] = category
            all_concepts.append(concept_copy)
    return all_concepts


def get_concepts_by_category(category: ConceptCategory) -> List[Dict[str, Any]]:
    """Get concepts for a specific category."""
    return CONCEPTS.get(category, {}).get("concepts", [])


def get_concept_by_key(key: str) -> Optional[Dict[str, Any]]:
    """Get a specific concept by key."""
    for category, data in CONCEPTS.items():
        for concept in data["concepts"]:
            if concept["key"] == key:
                concept_copy = concept.copy()
                concept_copy["category"] = data["name"]
                concept_copy["category_key"] = category
                return concept_copy
    return None


def get_random_concepts(count: int = 5, diverse: bool = True) -> List[Dict[str, Any]]:
    """Get random concepts, optionally ensuring diversity across categories."""
    if diverse:
        selected = []
        categories = list(CONCEPTS.keys())
        random.shuffle(categories)
        
        for category in categories[:count]:
            concepts = CONCEPTS[category]["concepts"]
            concept = random.choice(concepts).copy()
            concept["category"] = CONCEPTS[category]["name"]
            concept["category_key"] = category
            selected.append(concept)
        
        return selected[:count]
    else:
        all_concepts = get_all_concepts()
        return random.sample(all_concepts, min(count, len(all_concepts)))


# Top performing concepts for initial testing
TOP_CONCEPTS = [
    "selfie_style", "problem_awareness", "side_by_side_table", 
    "relatable_moment", "testimonial_screenshot"
]


def get_top_concepts() -> List[Dict[str, Any]]:
    """Get top performing concepts for initial testing."""
    return [get_concept_by_key(key) for key in TOP_CONCEPTS if get_concept_by_key(key)]


def get_compatible_concepts(angle_trigger: str) -> List[Dict[str, Any]]:
    """Get concepts compatible with a psychological trigger.
    Note: Visual layouts (before_after, split_screen, etc.) are now in visuals.py
    """
    # Compatibility mapping - concepts only (not visual layouts)
    compatibility = {
        "Fear": ["shock_headline", "problem_awareness", "micro_story", "visual_tension"],
        "Relief": ["relief_moment", "success_moment", "turning_point", "emotional_snapshot"],
        "Greed": ["price_stack", "value_breakdown", "side_by_side_table", "ranking"],
        "FOMO": ["countdown_cta", "crowd", "community", "urgent"],
        "Social Proof": ["testimonial_screenshot", "real_customer", "crowd", "ugc_collage"],
        "Authority": ["expert_portrait", "badge_seal", "data_backed", "certification"],
        "Curiosity": ["shock_headline", "unexpected_image", "pattern_break", "bold_claim"],
        "Pride": ["success_moment", "winner_highlight", "milestone_moment"],
        "Convenience": ["three_step", "how_it_works", "simple_explainer"],
        "Trust": ["trust_signals", "badge_seal", "real_customer", "testimonial_screenshot"],
    }
    
    concept_keys = compatibility.get(angle_trigger, [])
    return [get_concept_by_key(key) for key in concept_keys if get_concept_by_key(key)]