""" 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)]