{
  "id": "zyBv0G4EeHomIfXd",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Shorts Creation v10 - Telegram Filming",
  "tags": [],
  "nodes": [
    {
      "id": "25d380bf-7e85-4b68-b5a1-ed31013a02af",
      "name": "Stage 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5888,
        1696
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 200,
        "content": "## Stage 3: AI Analysis\n\nGPT-4o:\n1. Analyzes transcript\n2. Identifies best moments\n3. Generates 3 concepts\n4. Creates full avatar scripts\n\nEach concept uses different\nsource material."
      },
      "typeVersion": 1
    },
    {
      "id": "03bd4748-2e0f-49be-8061-49491f0249d2",
      "name": "Stage 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        6784,
        1696
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 200,
        "content": "## Stage 4: HeyGen Avatar\n\n**Single API Call**\n\nGenerates ONE video with:\n- Hook (5-8 sec)\n- Body narration (25-40 sec)\n- CTA (3-5 sec)\n\nDimensions: 1080x1920 (vertical)"
      },
      "typeVersion": 1
    },
    {
      "id": "8639a448-1fb7-4223-8559-9dcfff630a48",
      "name": "Stage 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        8672,
        1696
      ],
      "parameters": {
        "color": 3,
        "width": 340,
        "height": 220,
        "content": "## Stage 5: AI Video Director\n\n**Dynamic Layouts**\n\nAI generates RenderScript with:\n- avatar_full (hook/cta)\n- split_screen (demo)\n- pip_overlay (focus)\n\nTransitions every 4-8 seconds!\n\nNo template required."
      },
      "typeVersion": 1
    },
    {
      "id": "cd82f2ca-ef7e-4216-9d3d-ead1076e97c2",
      "name": "Loop Through Concepts",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2592,
        1920
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "11a9919e-ab3a-42e6-9fc4-dd44c73b721f",
      "name": "HeyGen - Generate Full Avatar",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3936,
        1744
      ],
      "parameters": {
        "url": "https://api.heygen.com/v2/video/generate",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={\n  \"video_inputs\": [\n    {\n      \"character\": {\n        \"type\": \"avatar\",\n        \"avatar_id\": \"{{ [\"e707a00d8b5549108f795f635d2de923\", \"eaa27b740b054bc18076968b9c5e3646\", \"e707a00d8b5549108f795f635d2de923\"][$('Loop Through Concepts').item.json.concept_number - 1] }}\",\n        \"avatar_style\": \"normal\"\n      },\n      \"voice\": {\n        \"type\": \"text\",\n        \"input_text\": {{ $('Loop Through Concepts').item.json.full_script.toJsonString() }},\n        \"voice_id\": \"8fac12c49e844f60aa672bff8273d154\",\n        \"speed\": 1.0,\n        \"pitch\": 5, \n        \"emotion\": \"Friendly\",  \n        \"stability\": 0.4,          \n        \"similarity_boost\": 0.85,  \n        \"style_exaggeration\": 0.5, \n        \"speaker_boost\": true\n      }\n    }\n  ],\n  \"dimension\": {\n    \"width\": 1920,\n    \"height\": 1080\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "dbb8ab81-5f14-498d-b182-8e498e0e7e2e",
      "name": "Set Avatar Video ID",
      "type": "n8n-nodes-base.set",
      "position": [
        4160,
        1744
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "avatar_video_id",
              "name": "avatar_video_id",
              "type": "string",
              "value": "={{ $json.data.video_id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "aa91af19-85a7-44b0-912e-334e4ef5b0bb",
      "name": "Poll Avatar Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4608,
        1664
      ],
      "parameters": {
        "url": "=https://api.heygen.com/v1/video_status.get?video_id={{ $('Set Avatar Video ID').item.json.avatar_video_id }}",
        "options": {},
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4f91bcc2-54a1-4f20-a92c-ea460f596d4d",
      "name": "Avatar Done?",
      "type": "n8n-nodes-base.if",
      "position": [
        4832,
        1744
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "avatar-done",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.data.status }}",
              "rightValue": "completed"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "4c36afcc-eeba-4dd1-b312-5b2dd8c35c19",
      "name": "Set Avatar URL",
      "type": "n8n-nodes-base.set",
      "position": [
        5056,
        1744
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "avatar_video_url",
              "name": "avatar_video_url",
              "type": "string",
              "value": "={{ $json.data.video_url }}"
            },
            {
              "id": "4a528e4d-7dfc-45c5-9dd7-762ccd5903bd",
              "name": "avatar_duration",
              "type": "number",
              "value": "={{ $json.data.duration }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6f445fdb-84d9-418c-b082-4bcf702cef22",
      "name": "Creatomate - Render",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        6000,
        1744
      ],
      "parameters": {
        "url": "https://api.creatomate.com/v2/renders",
        "method": "POST",
        "options": {
          "timeout": 120000
        },
        "jsonBody": "={{ $json}}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "43290299-e7b3-472d-afdf-d281eab6bcae",
      "name": "Set Render ID",
      "type": "n8n-nodes-base.set",
      "position": [
        6224,
        1744
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "render_id",
              "name": "render_id",
              "type": "string",
              "value": "={{ Array.isArray($json) ? $json[0].id : $json.id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9410f289-7181-4c5a-8194-e67fa6d94675",
      "name": "Wait for Render",
      "type": "n8n-nodes-base.wait",
      "position": [
        6448,
        1744
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "15b534ae-3780-4ddc-a957-7e5b2f35b113",
      "name": "Poll Render Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        6672,
        1664
      ],
      "parameters": {
        "url": "=https://api.creatomate.com/v2/renders/{{ $('Set Render ID').item.json.render_id }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "cfdd0819-a613-487a-ae58-47f6be30d7d1",
      "name": "Render Done?",
      "type": "n8n-nodes-base.if",
      "position": [
        6896,
        1744
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "render-done",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "succeeded"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "9360db52-8aad-49f0-9bdd-ed4ea1f6e9e9",
      "name": "Download Rendered Video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        7120,
        1744
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e0c53c3c-fdb2-42e0-8d9e-2f97e639d1e3",
      "name": "Upload to Google Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        7344,
        1744
      ],
      "parameters": {
        "name": "={{ $('AI Video Director').item.json.output[0].content[0].text.title }}_{{ $('Loop Through Concepts').item.json.concept_index }}.mp4",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1KnH7S9ltO1VMhahtNQcKLkUnFwekbOqL",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1KnH7S9ltO1VMhahtNQcKLkUnFwekbOqL",
          "cachedResultName": "Adam Goodyer Short-Form Content"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "c569730f-a65d-4d44-9ebf-36e9a0662fdf",
      "name": "Creatomate Template Builder Code1",
      "type": "n8n-nodes-base.code",
      "position": [
        5776,
        1744
      ],
      "parameters": {
        "jsCode": "// ============================================================\n// CREATOMATE TEMPLATE BUILDER v23.0 (STEPPED FLASH FIXED)\n// ============================================================\n// \n// FIX v23.0:\n// - FIXED: Flash now uses SEQUENTIAL COMPOSITIONS on same track\n// - Each composition has rgba opacity baked into fill_color\n// - No animations needed - stepped opacity creates smooth fade-out\n// - Compositions with empty elements[] act as solid color overlays\n// - Zoom animation uses back-out easing for punch feel\n//\n// ============================================================\n\n// ============================================================\n// \ud83c\udf9b\ufe0f INPUT NODES - All data sources in one place\n// ============================================================\n\nconst INPUT_NODES = {\n  aiDirector: $('AI Video Director').first().json,\n  conceptLoop: $('Loop Through Concepts').first().json,\n  avatarUrl: $('Set Avatar URL').first().json,\n  flashBroll: $('Aggregate Flash B-Roll').first().json,\n  effectsLibrary: $('Creatomate Effects Library').first().json,\n  shortsSource: $('Shorts Trigger').first().json?.source || {}\n};\n\n// ============================================================\n// \ud83c\udf9b\ufe0f CONFIGURABLE SETTINGS\n// ============================================================\n\n// Video Output Settings\nconst VIDEO_SETTINGS = {\n  outputFormat: 'mp4',\n  width: 1080,\n  height: 1920,\n  frameRate: 30,\n  previewWidth: 1080,\n  previewHeight: 1920,\n  usePreviewSize: true\n};\n\n// ============================================================\n// \ud83d\ude80 SCROLL-STOPPER INTRO SETTINGS (STEPPED COMPOSITION APPROACH)\n// ============================================================\n// \n// Psychology of short-form scroll-stopping:\n// 1. INSTANT IMPACT: White flash at frame 0 triggers attention\n// 2. MOTION PARALLAX: Zoom creates depth, signals \"something happening\"\n// 3. TIMING: Must complete < 0.5s to not annoy, but long enough to register\n// 4. CONTRAST: White on dark background = maximum visual punch\n//\n// TECHNICAL: Uses sequential compositions on same track with\n// decreasing rgba opacity baked into fill_color. This creates\n// a smooth stepped fade-out effect without needing animations.\n//\n// ============================================================\n\nconst INTRO_EFFECT = {\n  enabled: true,\n  \n  // Stepped flash using sequential compositions\n  // Each step is a composition with opacity in rgba fill_color\n  flash: {\n    enabled: true,\n    baseTrack: 30,  // High track = renders on top\n    steps: [\n      // Step 1: FULL PUNCH - 100% white (quick hit)\n      { time: 0,     duration: 0.017, opacity: 1.0 },\n      // Step 2: 80% white\n      { time: 0.017, duration: 0.017, opacity: 0.8 },\n      // Step 3: 55% white\n      { time: 0.034, duration: 0.017, opacity: 0.55 },\n      // Step 4: 30% white\n      { time: 0.051, duration: 0.025, opacity: 0.3 },\n      // Step 5: 15% white\n      { time: 0.076, duration: 0.035, opacity: 0.15 },\n      // Step 6: 5% white (quick fade out)\n      { time: 0.111, duration: 0.04,  opacity: 0.05 }\n    ]\n  },\n  \n  // Zoom settings - creates depth and \"impact\" feeling\n  zoom: {\n    enabled: true,\n    startScale: \"150%\",       // Start zoomed in more for punch\n    endScale: \"100%\",         // Settle to normal\n    duration: 0.4,            // Quick but not jarring\n    easing: \"back-out\"        // Overshoots slightly for punch feel\n  }\n};\n\n// Screen Recording Glow Effect\nconst SCREEN_GLOW = {\n  enabled: true,\n  color: '#355A15',\n  primaryOpacity: '60%',\n  secondaryOpacity: '40%',\n  primaryBlur: '25 vmin',\n  secondaryBlur: '15 vmin'\n};\n\n// Caption Settings\nconst CAPTION_SETTINGS = {\n  enabled: true,\n  fontFamily: 'Montserrat',\n  fontWeight: 900,\n  fontSize: '9.5 vmin',\n  fillColor: '#FFFFFF',\n  strokeColor: '#000000',\n  strokeWidth: '1.1 vmin',\n  shadowColor: 'rgba(0,0,0,0.95)',\n  shadowBlur: '1.3 vmin',\n  maxLength: 14,\n  effect: 'highlight',\n  positionY: '68%'\n};\n\n// Background Settings\nconst BACKGROUND = {\n  color: '#0a0a0a'\n};\n\n// Audio Settings\nconst AUDIO_SETTINGS = {\n  baseUrl: 'https://pub-1710591b286a4bf3877267e2ce0828e1.r2.dev',\n  defaultVolume: '7%',\n  fadeIn: 0.5,\n  fadeOut: 1.5\n};\n\n// ============================================================\n// \ud83d\udce5 PARSE AI DIRECTOR OUTPUT\n// ============================================================\n\nlet directorData;\nconst aiOutput = INPUT_NODES.aiDirector.output;\n\nif (aiOutput && typeof aiOutput === 'object' && !Array.isArray(aiOutput)) {\n  directorData = aiOutput;\n} else if (Array.isArray(aiOutput)) {\n  try {\n    const messageBlock = aiOutput.find(o => o.type === 'message');\n    if (messageBlock) {\n      const textContent = messageBlock.content[0].text;\n      directorData = typeof textContent === 'string' \n        ? JSON.parse(textContent) \n        : textContent;\n    } else {\n      const textContent = aiOutput[1]?.content?.[0]?.text;\n      directorData = typeof textContent === 'string' \n        ? JSON.parse(textContent) \n        : textContent;\n    }\n  } catch (e) {\n    console.error('Parse error:', e.message);\n    directorData = {};\n  }\n} else {\n  directorData = {};\n}\n\n// ============================================================\n// \ud83d\udcca DERIVED CONSTANTS\n// ============================================================\n\nconst conceptData = INPUT_NODES.conceptLoop;\nconst avatarUrl = INPUT_NODES.avatarUrl.avatar_video_url;\nconst avatarDuration = INPUT_NODES.avatarUrl.avatar_duration || INPUT_NODES.avatarUrl.duration || null;\nconst flashBrollGenerated = INPUT_NODES.flashBroll.flash_broll_generated || [];\nconst lib = INPUT_NODES.effectsLibrary;\nconst sourceData = INPUT_NODES.shortsSource;\n\n// Build AI B-roll URL lookup\nconst aiBrollUrls = {};\nflashBrollGenerated.forEach(clip => {\n  const index = (clip.flash_number || 1) - 1;\n  aiBrollUrls[index] = clip.video_url;\n});\n\n// Storyboard and styling\nconst storyboard = directorData.enhanced_storyboard || directorData.storyboard || [];\nconst conceptType = directorData.concept_type || conceptData.concept_type || 'bold';\nconst accentColor = lib.accent_colors?.[conceptType] || lib.accent_colors?.[Object.keys(lib.accent_colors || {})[0]] || '#00E676';\n\n// Final constants\nconst AVATAR_URL = avatarUrl;\nconst SCREEN_URL = sourceData.video_url || directorData.video_url;\nconst AI_BROLL_URLS = aiBrollUrls;\nconst STORYBOARD = storyboard;\nconst ACTUAL_AVATAR_DURATION = avatarDuration || directorData.total_duration_seconds || directorData.total_duration;\nconst ACCENT_COLOR = accentColor;\n\n// Audio track selection\nconst audioTrackId = directorData.audio_track || Object.keys(lib.audio_tracks || {})[0] || 7;\nconst selectedTrack = lib.audio_tracks?.[audioTrackId];\n\n// ============================================================\n// \ud83d\udd27 HELPER FUNCTIONS\n// ============================================================\n\nfunction getDefaultLayout() {\n  const layoutKeys = Object.keys(lib.layouts || {});\n  const withAvatar = layoutKeys.find(k => lib.layouts[k].avatar);\n  const anyLayout = layoutKeys[0];\n  \n  if (withAvatar) return lib.layouts[withAvatar];\n  if (anyLayout) return lib.layouts[anyLayout];\n  \n  return {\n    id: \"FALLBACK\",\n    avatar: { x: \"50%\", y: \"50%\", width: \"100%\", height: \"100%\" },\n    screen: null,\n    divider_y: null\n  };\n}\n\nfunction getLayout(layoutId) {\n  if (layoutId && lib.layouts?.[layoutId]) {\n    return lib.layouts[layoutId];\n  }\n  return getDefaultLayout();\n}\n\n// ============================================================\n// \ud83c\udfac TRANSITION SYSTEM (DYNAMIC FROM EFFECTS LIBRARY)\n// ============================================================\n\nconst OVERLAY_TRANSITION_TYPES = [\n  'flash', 'double_flash', 'rgb_glitch', 'accent_flash', \n  'glitch_bars', 'zoom_shake', 'whip_pan'\n];\n\nfunction isOverlayTransition(transitionId) {\n  if (!transitionId) return false;\n  const trans = lib.transitions?.[transitionId];\n  if (!trans) return false;\n  return OVERLAY_TRANSITION_TYPES.includes(trans.type);\n}\n\n// ============================================================\n// \ud83d\ude80 SCROLL-STOPPER INTRO BUILDERS (STEPPED COMPOSITION APPROACH)\n// ============================================================\n\n/**\n * Build intro flash overlay elements using STEPPED COMPOSITIONS.\n * \n * KEY INSIGHT: Creatomate's fade animations don't support fade-OUT.\n * Instead, we use sequential compositions on the SAME TRACK with\n * decreasing rgba opacity baked into fill_color. This creates a\n * smooth stepped fade-out effect without needing any animations.\n * \n * - All compositions on same track = they play SEQUENTIALLY\n * - Each has explicit time + duration for precise control\n * - Opacity is in rgba format: \"rgba(255,255,255,0.75)\"\n * - Empty elements[] array = solid color overlay\n * \n * @returns {Array} Array of composition elements for the flash effect\n */\nfunction buildIntroFlashElements() {\n  if (!INTRO_EFFECT.enabled || !INTRO_EFFECT.flash.enabled) return [];\n  \n  const flashElements = [];\n  const track = INTRO_EFFECT.flash.baseTrack;\n  \n  INTRO_EFFECT.flash.steps.forEach((step) => {\n    flashElements.push({\n      type: \"composition\",\n      track: track,  // ALL on same track = sequential playback\n      time: step.time,\n      duration: step.duration,\n      fill_color: `rgba(255,255,255,${step.opacity})`,  // Opacity baked in!\n      width: \"100%\",\n      height: \"100%\",\n      elements: []  // Empty = solid color overlay\n    });\n  });\n  \n  return flashElements;\n}\n\n/**\n * Build intro zoom animation using PROPER Creatomate syntax.\n * \n * Uses back-out easing for that \"punch\" feel where it slightly\n * overshoots then settles back. Combined with flash, creates\n * the scroll-stopping impact moment.\n * \n * @returns {Object|null} Animation object for the animations array\n */\nfunction buildIntroZoomAnimation() {\n  if (!INTRO_EFFECT.enabled || !INTRO_EFFECT.zoom.enabled) return null;\n  \n  return {\n    type: \"scale\",\n    time: 0,  // Start immediately\n    duration: INTRO_EFFECT.zoom.duration,\n    easing: INTRO_EFFECT.zoom.easing,\n    start_scale: INTRO_EFFECT.zoom.startScale,\n    end_scale: INTRO_EFFECT.zoom.endScale,\n    scope: \"element\",\n    fade: false\n  };\n}\n\n// ============================================================\n// \ud83c\udfac OTHER TRANSITION/ANIMATION HELPERS\n// ============================================================\n\nfunction buildTransitionOverlays(time, transitionId) {\n  const trans = lib.transitions?.[transitionId];\n  if (!trans) return [];\n  \n  const elements = [];\n  let trackOffset = 20;\n  \n  switch (trans.type) {\n    case 'flash':\n    case 'double_flash':\n      // Use stepped composition approach for mid-video flashes too\n      const flashSteps = [\n        { timeOffset: 0,     duration: 0.03, opacity: 1.0 },\n        { timeOffset: 0.03,  duration: 0.03, opacity: 0.7 },\n        { timeOffset: 0.06,  duration: 0.04, opacity: 0.4 },\n        { timeOffset: 0.10,  duration: 0.05, opacity: 0.15 }\n      ];\n      flashSteps.forEach((step, i) => {\n        elements.push({\n          type: \"composition\",\n          track: trackOffset + i,\n          time: time + step.timeOffset,\n          duration: step.duration,\n          fill_color: `rgba(255,255,255,${step.opacity})`,\n          width: \"100%\",\n          height: \"100%\",\n          elements: []\n        });\n      });\n      break;\n    \n    case 'rgb_glitch':\n      // Build RGB color layers\n      const rgbSteps = [\n        { color: \"255,0,0\", opacity: 0.5, xOffset: \"-2%\" },\n        { color: \"0,255,0\", opacity: 0.5, xOffset: \"0%\" },\n        { color: \"0,0,255\", opacity: 0.5, xOffset: \"2%\" }\n      ];\n      rgbSteps.forEach((layer, i) => {\n        elements.push({\n          type: \"composition\",\n          track: trackOffset + i,\n          time: time,\n          duration: trans.duration || 0.12,\n          fill_color: `rgba(${layer.color},${layer.opacity})`,\n          width: \"100%\",\n          height: \"100%\",\n          x: layer.xOffset,\n          blend_mode: \"screen\",\n          elements: []\n        });\n      });\n      // Follow-up white flash\n      const whiteFlashSteps = [\n        { timeOffset: 0,    duration: 0.03, opacity: 1.0 },\n        { timeOffset: 0.03, duration: 0.05, opacity: 0.5 },\n        { timeOffset: 0.08, duration: 0.07, opacity: 0.15 }\n      ];\n      whiteFlashSteps.forEach((step, i) => {\n        elements.push({\n          type: \"composition\",\n          track: trackOffset + rgbSteps.length + i,\n          time: time + (trans.duration || 0.12) * 0.5 + step.timeOffset,\n          duration: step.duration,\n          fill_color: `rgba(255,255,255,${step.opacity})`,\n          width: \"100%\",\n          height: \"100%\",\n          elements: []\n        });\n      });\n      break;\n    \n    case 'accent_flash':\n      // Accent color punch followed by white\n      const accentSteps = [\n        { timeOffset: 0,    duration: 0.04, opacity: 0.7, color: ACCENT_COLOR.replace('#', '') },\n        { timeOffset: 0.04, duration: 0.04, opacity: 0.3, color: ACCENT_COLOR.replace('#', '') }\n      ];\n      // Convert hex to rgb for accent\n      const hexToRgb = (hex) => {\n        const r = parseInt(hex.substring(0, 2), 16);\n        const g = parseInt(hex.substring(2, 4), 16);\n        const b = parseInt(hex.substring(4, 6), 16);\n        return `${r},${g},${b}`;\n      };\n      const accentRgb = hexToRgb(ACCENT_COLOR.replace('#', ''));\n      accentSteps.forEach((step, i) => {\n        elements.push({\n          type: \"composition\",\n          track: trackOffset + i,\n          time: time + step.timeOffset,\n          duration: step.duration,\n          fill_color: `rgba(${accentRgb},${step.opacity})`,\n          width: \"100%\",\n          height: \"100%\",\n          elements: []\n        });\n      });\n      // White flash after accent\n      const whiteAfterAccent = [\n        { timeOffset: 0.05, duration: 0.03, opacity: 1.0 },\n        { timeOffset: 0.08, duration: 0.04, opacity: 0.6 },\n        { timeOffset: 0.12, duration: 0.08, opacity: 0.2 }\n      ];\n      whiteAfterAccent.forEach((step, i) => {\n        elements.push({\n          type: \"composition\",\n          track: trackOffset + accentSteps.length + i,\n          time: time + step.timeOffset,\n          duration: step.duration,\n          fill_color: `rgba(255,255,255,${step.opacity})`,\n          width: \"100%\",\n          height: \"100%\",\n          elements: []\n        });\n      });\n      break;\n    \n    case 'zoom_shake':\n      // White flash with zoom feel\n      const zoomFlashSteps = [\n        { timeOffset: 0,    duration: 0.04, opacity: 1.0 },\n        { timeOffset: 0.04, duration: 0.06, opacity: 0.6 },\n        { timeOffset: 0.10, duration: 0.10, opacity: 0.25 },\n        { timeOffset: 0.20, duration: 0.10, opacity: 0.08 }\n      ];\n      zoomFlashSteps.forEach((step, i) => {\n        elements.push({\n          type: \"composition\",\n          track: trackOffset + i,\n          time: time + step.timeOffset,\n          duration: step.duration,\n          fill_color: `rgba(255,255,255,${step.opacity})`,\n          width: \"100%\",\n          height: \"100%\",\n          elements: []\n        });\n      });\n      break;\n    \n    case 'whip_pan':\n      // Horizontal wipe-style flash\n      elements.push({\n        type: \"composition\",\n        track: trackOffset,\n        time: time,\n        duration: trans.duration || 0.15,\n        fill_color: \"rgba(255,255,255,1)\",\n        width: trans.width || \"120%\",\n        height: \"100%\",\n        y: \"50%\",\n        x_anchor: \"50%\",\n        y_anchor: \"50%\",\n        elements: [],\n        animations: [\n          {\n            type: \"slide\",\n            time: 0,\n            duration: trans.duration || 0.15,\n            direction: \"0\u00b0\",\n            distance: \"120%\",\n            easing: \"quadratic-out\"\n          }\n        ]\n      });\n      break;\n    \n    default:\n      // Generic flash fallback using stepped approach\n      if (trans.color) {\n        const genericSteps = [\n          { timeOffset: 0,    duration: 0.03, opacity: 1.0 },\n          { timeOffset: 0.03, duration: 0.05, opacity: 0.5 },\n          { timeOffset: 0.08, duration: 0.07, opacity: 0.15 }\n        ];\n        genericSteps.forEach((step, i) => {\n          elements.push({\n            type: \"composition\",\n            track: trackOffset + i,\n            time: time + step.timeOffset,\n            duration: step.duration,\n            fill_color: `rgba(255,255,255,${step.opacity})`,\n            width: \"100%\",\n            height: \"100%\",\n            elements: []\n          });\n        });\n      }\n  }\n  \n  return elements;\n}\n\nfunction buildTransitionAnimation(transitionId) {\n  if (!transitionId) return null;\n  \n  const trans = lib.transitions?.[transitionId];\n  if (!trans) return null;\n  \n  if (OVERLAY_TRANSITION_TYPES.includes(trans.type)) return null;\n  if (trans.type === 'cut') return null;\n  \n  const animation = {\n    time: 0,\n    duration: trans.duration || 0.15,\n    transition: true,\n    easing: trans.easing || \"quadratic-out\"\n  };\n  \n  switch (trans.type) {\n    case 'scale':\n      animation.type = \"scale\";\n      animation.start_scale = trans.start_scale || \"120%\";\n      break;\n      \n    case 'slide':\n      animation.type = \"slide\";\n      animation.direction = trans.direction || \"0\u00b0\";\n      if (trans.distance) animation.distance = trans.distance;\n      animation.fade = trans.fade !== undefined ? trans.fade : false;\n      break;\n      \n    case 'wipe':\n      animation.type = \"wipe\";\n      animation.direction = trans.direction || \"left\";\n      break;\n      \n    case 'fade':\n      animation.type = \"fade\";\n      break;\n      \n    default:\n      return null;\n  }\n  \n  return animation;\n}\n\nfunction getAvatarAnimation(animationId) {\n  if (!animationId) return [];\n  \n  const anim = lib.avatar_animations?.[animationId];\n  if (!anim || anim.type === 'none') return [];\n  \n  switch (anim.type) {\n    case 'scale':\n      return [{ \n        type: \"scale\", \n        time: 0, \n        duration: anim.duration || 0.2, \n        start_scale: anim.start_scale || \"108%\", \n        easing: anim.easing || \"quadratic-out\"\n      }];\n      \n    case 'slide':\n      return [{ \n        type: \"slide\", \n        time: 0, \n        duration: anim.duration || 0.25, \n        direction: anim.direction === 'up' ? \"90\u00b0\" : \"270\u00b0\",\n        distance: anim.distance || \"10%\",\n        easing: anim.easing || \"back-out\"\n      }];\n      \n    case 'fade':\n      return [{\n        type: \"fade\",\n        time: 0,\n        duration: anim.duration || 0.3,\n        start_opacity: anim.start_opacity || \"0%\"\n      }];\n      \n    default:\n      return [];\n  }\n}\n\nfunction getScreenMotion(motionId, duration) {\n  const defaultMotion = { \n    scale: [{ time: \"0 s\", value: \"100%\" }], \n    x: [{ time: \"0 s\", value: \"50%\" }], \n    y: [{ time: \"0 s\", value: \"50%\" }] \n  };\n  \n  if (!motionId) return defaultMotion;\n  \n  const motion = lib.screen_motions?.[motionId];\n  if (!motion) return defaultMotion;\n  \n  if (motion.type === 'static') return defaultMotion;\n  \n  if (motion.type === 'zoom') {\n    return {\n      scale: [\n        { time: \"0 s\", value: motion.start_scale || \"100%\", easing: motion.easing || \"linear\" },\n        { time: `${duration} s`, value: motion.end_scale || \"108%\" }\n      ],\n      x: [{ time: \"0 s\", value: \"50%\" }],\n      y: [{ time: \"0 s\", value: \"50%\" }]\n    };\n  }\n  \n  if (motion.type === 'pan') {\n    return {\n      scale: [{ time: \"0 s\", value: \"100%\" }],\n      x: [\n        { time: \"0 s\", value: motion.start_x || \"50%\", easing: motion.easing || \"linear\" },\n        { time: `${duration} s`, value: motion.end_x || \"50%\" }\n      ],\n      y: [\n        { time: \"0 s\", value: motion.start_y || \"50%\", easing: motion.easing || \"linear\" },\n        { time: `${duration} s`, value: motion.end_y || \"50%\" }\n      ]\n    };\n  }\n  \n  return defaultMotion;\n}\n\nfunction buildTextOverlay(styleId, content, time, duration) {\n  if (!styleId || !content) return null;\n  \n  const style = lib.text_styles?.[styleId];\n  if (!style) return null;\n  \n  const fillColor = (style.fill_color || \"#FFFFFF\").replace(\"{{ACCENT_COLOR}}\", ACCENT_COLOR);\n  const bgColor = style.background_color?.replace(\"{{ACCENT_COLOR}}\", ACCENT_COLOR);\n  \n  const textElement = {\n    type: \"text\",\n    track: 10,\n    time: time + 0.2,\n    duration: duration - 0.3,\n    text: content,\n    x: style.position?.x || \"50%\",\n    y: style.position?.y || \"78%\",\n    width: \"92%\",\n    x_anchor: \"50%\",\n    y_anchor: \"50%\",\n    x_alignment: \"50%\",\n    font_family: style.font_family,\n    font_weight: style.font_weight,\n    font_size: style.font_size,\n    fill_color: fillColor,\n    animations: [\n      { type: \"scale\", time: 0, duration: 0.25, easing: \"back-out\", start_scale: \"90%\" },\n      { type: \"fade\", time: \"end\", duration: 0.15 }\n    ]\n  };\n  \n  if (style.stroke_color) textElement.stroke_color = style.stroke_color;\n  if (style.stroke_width) textElement.stroke_width = style.stroke_width;\n  if (style.shadow_color) textElement.shadow_color = style.shadow_color;\n  if (style.shadow_blur) textElement.shadow_blur = style.shadow_blur;\n  if (bgColor) textElement.background_color = bgColor;\n  if (style.background_x_padding) textElement.background_x_padding = style.background_x_padding;\n  if (style.background_y_padding) textElement.background_y_padding = style.background_y_padding;\n  if (style.background_border_radius) textElement.background_border_radius = style.background_border_radius;\n  \n  return textElement;\n}\n\nfunction getBrollVideoUrl(beat) {\n  if (beat.broll_type === 'screen') return SCREEN_URL;\n  if (beat.broll_type === 'ai_generated' && beat.ai_broll_index != null && beat.ai_broll_index >= 0) {\n    return AI_BROLL_URLS[beat.ai_broll_index] || null;\n  }\n  return null;\n}\n\nfunction getBrollTrimSettings(beat, duration) {\n  if (beat.broll_type === 'screen') {\n    const startTime = beat.broll_start_seconds || 0;\n    const aiSpecifiedDuration = beat.broll_end_seconds && beat.broll_start_seconds \n      ? beat.broll_end_seconds - beat.broll_start_seconds \n      : null;\n    \n    return {\n      trim_start: startTime,\n      trim_duration: duration + 0.5,\n      _ai_specified_duration: aiSpecifiedDuration,\n      _was_corrected: aiSpecifiedDuration !== null && aiSpecifiedDuration < duration\n    };\n  }\n  \n  if (beat.broll_type === 'ai_generated') {\n    return { \n      trim_start: 0, \n      trim_duration: duration + 0.5\n    };\n  }\n  \n  return null;\n}\n\n// ============================================================\n// \ud83c\udfd7\ufe0f BUILD ELEMENTS ARRAY\n// ============================================================\n\nconst elements = [];\nlet avatarTrimPosition = 0;\nlet overlayTransitionCount = 0;\nlet brollDurationCorrections = [];\nlet introFlashCount = 0;\nlet introZoomApplied = false;\n\n// Track 1: Background Music\nif (selectedTrack) {\n  elements.push({\n    type: \"audio\",\n    track: 1,\n    source: `${AUDIO_SETTINGS.baseUrl}/${selectedTrack.file || selectedTrack.name.toLowerCase().replace(/ /g, '_') + '.mp3'}`,\n    volume: selectedTrack.volume || AUDIO_SETTINGS.defaultVolume,\n    loop: true,\n    audio_fade_in: AUDIO_SETTINGS.fadeIn,\n    audio_fade_out: AUDIO_SETTINGS.fadeOut\n  });\n}\n\n// Track 2: Master Avatar (hidden, for audio & caption sync)\nelements.push({\n  id: \"avatar-master\",\n  type: \"video\",\n  track: 2,\n  time: 0,\n  source: AVATAR_URL,\n  volume: \"100%\",\n  y: \"200%\",\n  fit: \"cover\"\n});\n\n// Track 3: Black Background\nelements.push({\n  type: \"shape\",\n  track: 3,\n  time: 0,\n  duration: ACTUAL_AVATAR_DURATION + 5,\n  shape: \"rectangle\",\n  width: \"100%\",\n  height: \"100%\",\n  fill_color: BACKGROUND.color\n});\n\n// ============================================================\n// \ud83d\ude80 ADD INTRO FLASH ELEMENTS (Track 30 - stepped compositions)\n// ============================================================\nconst introFlashElements = buildIntroFlashElements();\nintroFlashElements.forEach(el => {\n  elements.push(el);\n  introFlashCount++;\n});\n\n// ============================================================\n// \ud83c\udfac PROCESS EACH STORYBOARD BEAT\n// ============================================================\n\nlet currentTime = 0;\n\nSTORYBOARD.forEach((beat, idx) => {\n  const duration = beat.duration_seconds || 4;\n  const layout = getLayout(beat.layout);\n  const screenMotion = getScreenMotion(beat.screen_motion, duration);\n  const avatarAnimations = getAvatarAnimation(beat.avatar_animation);\n  \n  const isIntroBeat = idx === 0;\n  \n  // Handle transitions (not for first beat)\n  let transitionAnimation = null;\n  if (!isIntroBeat && beat.transition_in) {\n    if (isOverlayTransition(beat.transition_in)) {\n      const overlayElements = buildTransitionOverlays(currentTime, beat.transition_in);\n      overlayElements.forEach(el => elements.push(el));\n      overlayTransitionCount++;\n    } else {\n      transitionAnimation = buildTransitionAnimation(beat.transition_in);\n    }\n  }\n  \n  // ============================================================\n  // AVATAR ELEMENT\n  // ============================================================\n  if (layout.avatar) {\n    const avatarElement = {\n      type: \"video\",\n      track: 4,\n      time: currentTime,\n      duration: duration,\n      source: AVATAR_URL,\n      trim_start: avatarTrimPosition,\n      trim_duration: duration,\n      volume: 0,\n      x: layout.avatar.x,\n      y: layout.avatar.y,\n      width: layout.avatar.width,\n      height: layout.avatar.height,\n      x_anchor: \"50%\",\n      y_anchor: \"50%\",\n      fit: \"cover\",\n      clip: true\n    };\n    \n    if (layout.avatar.border_radius) {\n      avatarElement.border_radius = layout.avatar.border_radius;\n    }\n    \n    // Build animations array\n    const allAnimations = [];\n    \n    // INTRO: First beat gets scroll-stopper zoom\n    if (isIntroBeat && INTRO_EFFECT.enabled && INTRO_EFFECT.zoom.enabled) {\n      const introZoom = buildIntroZoomAnimation();\n      if (introZoom) {\n        allAnimations.push(introZoom);\n        introZoomApplied = true;\n      }\n    } else {\n      if (transitionAnimation) allAnimations.push(transitionAnimation);\n      avatarAnimations.forEach(a => allAnimations.push(a));\n    }\n    \n    if (allAnimations.length > 0) {\n      avatarElement.animations = allAnimations;\n    }\n    \n    elements.push(avatarElement);\n  }\n  \n  // ============================================================\n  // B-ROLL ELEMENT\n  // ============================================================\n  const brollUrl = getBrollVideoUrl(beat);\n  const brollTrim = getBrollTrimSettings(beat, duration);\n  \n  if (brollTrim && brollTrim._was_corrected) {\n    brollDurationCorrections.push({\n      beat_index: idx,\n      beat_type: beat.beat_type,\n      beat_duration: duration,\n      ai_specified_duration: brollTrim._ai_specified_duration,\n      correction_applied: true\n    });\n  }\n  \n  if (layout.screen && brollUrl && brollTrim) {\n    \n    const isScreenRecording = beat.broll_type === 'screen' || layout.is_padded_screen === true;\n    const fitMode = isScreenRecording ? 'contain' : 'cover';\n    \n    const videoWidth = isScreenRecording ? '92%' : '120%';\n    const videoHeight = isScreenRecording ? '88%' : '130%';\n    \n    const innerElements = [];\n    \n    if (isScreenRecording && SCREEN_GLOW.enabled) {\n      innerElements.push({\n        type: \"shape\",\n        track: 1,\n        shape: \"rectangle\",\n        width: \"100%\",\n        height: \"100%\",\n        fill_color: \"#0d0d0d\"\n      });\n      \n      innerElements.push({\n        type: \"shape\",\n        track: 2,\n        shape: \"rectangle\",\n        width: \"70%\",\n        height: \"60%\",\n        x: \"50%\",\n        y: \"50%\",\n        x_anchor: \"50%\",\n        y_anchor: \"50%\",\n        fill_color: SCREEN_GLOW.color,\n        opacity: SCREEN_GLOW.primaryOpacity,\n        shadow_color: SCREEN_GLOW.color,\n        shadow_blur: SCREEN_GLOW.primaryBlur,\n        border_radius: \"5 vmin\"\n      });\n      \n      innerElements.push({\n        type: \"shape\",\n        track: 3,\n        shape: \"rectangle\",\n        width: \"50%\",\n        height: \"40%\",\n        x: \"50%\",\n        y: \"50%\",\n        x_anchor: \"50%\",\n        y_anchor: \"50%\",\n        fill_color: SCREEN_GLOW.color,\n        opacity: SCREEN_GLOW.secondaryOpacity,\n        shadow_color: SCREEN_GLOW.color,\n        shadow_blur: SCREEN_GLOW.secondaryBlur,\n        border_radius: \"3 vmin\"\n      });\n      \n      innerElements.push({\n        type: \"shape\",\n        track: 4,\n        shape: \"rectangle\",\n        width: \"93%\",\n        height: \"89%\",\n        x: \"50%\",\n        y: \"50%\",\n        x_anchor: \"50%\",\n        y_anchor: \"50%\",\n        fill_color: \"#0a0a0a\",\n        border_radius: \"1.2 vmin\",\n        shadow_color: \"rgba(0,0,0,0.8)\",\n        shadow_blur: \"2 vmin\"\n      });\n    }\n    \n    innerElements.push({\n      type: \"video\",\n      track: 5,\n      source: brollUrl,\n      volume: 0,\n      trim_start: brollTrim.trim_start,\n      trim_duration: brollTrim.trim_duration,\n      x: \"50%\",\n      y: \"50%\",\n      x_anchor: \"50%\",\n      y_anchor: \"50%\",\n      width: videoWidth,\n      height: videoHeight,\n      fit: fitMode,\n      border_radius: isScreenRecording ? \"1 vmin\" : \"0\",\n      ...screenMotion\n    });\n    \n    if (isScreenRecording && SCREEN_GLOW.enabled) {\n      innerElements.push({\n        type: \"shape\",\n        track: 6,\n        shape: \"rectangle\",\n        width: \"92%\",\n        height: \"88%\",\n        x: \"50%\",\n        y: \"50%\",\n        x_anchor: \"50%\",\n        y_anchor: \"50%\",\n        fill_color: \"rgba(0,0,0,0)\",\n        border_color: \"rgba(255,255,255,0.1)\",\n        border_width: \"0.3 vmin\",\n        border_radius: \"1 vmin\"\n      });\n    }\n    \n    const compositionElement = {\n      type: \"composition\",\n      track: 5,\n      time: currentTime,\n      duration: duration,\n      x: layout.screen.x,\n      y: layout.screen.y,\n      width: layout.screen.width,\n      height: layout.screen.height,\n      x_anchor: \"50%\",\n      y_anchor: \"50%\",\n      clip: true,\n      elements: innerElements\n    };\n    \n    // INTRO: First beat gets scroll-stopper zoom on screen too\n    if (isIntroBeat && INTRO_EFFECT.enabled && INTRO_EFFECT.zoom.enabled) {\n      const introZoom = buildIntroZoomAnimation();\n      if (introZoom) compositionElement.animations = [introZoom];\n    } else if (!layout.avatar && transitionAnimation) {\n      compositionElement.animations = [transitionAnimation];\n    }\n    \n    elements.push(compositionElement);\n  }\n  \n  // ============================================================\n  // DIVIDER LINE\n  // ============================================================\n  if (layout.divider_y) {\n    elements.push({\n      type: \"shape\",\n      track: 6,\n      time: currentTime,\n      duration: duration,\n      shape: \"rectangle\",\n      x: \"50%\",\n      y: layout.divider_y,\n      width: \"100%\",\n      height: \"0.5%\",\n      x_anchor: \"50%\",\n      y_anchor: \"50%\",\n      fill_color: ACCENT_COLOR,\n      shadow_color: \"rgba(0,0,0,0.5)\",\n      shadow_blur: \"0.5 vmin\"\n    });\n  }\n  \n  // ============================================================\n  // TEXT OVERLAY\n  // ============================================================\n  if (beat.text_overlay && beat.text_content) {\n    const textElement = buildTextOverlay(beat.text_overlay, beat.text_content, currentTime, duration);\n    if (textElement) elements.push(textElement);\n  }\n  \n  currentTime += duration;\n  avatarTrimPosition += duration;\n});\n\n// ============================================================\n// \ud83d\udcdd AUTO-CAPTIONS\n// ============================================================\nif (CAPTION_SETTINGS.enabled) {\n  elements.push({\n    type: \"text\",\n    track: 11,\n    transcript_source: \"avatar-master\",\n    transcript_effect: CAPTION_SETTINGS.effect,\n    transcript_maximum_length: CAPTION_SETTINGS.maxLength,\n    x: \"50%\",\n    y: CAPTION_SETTINGS.positionY,\n    width: \"90%\",\n    height: \"20%\",\n    x_anchor: \"50%\",\n    y_anchor: \"50%\",\n    x_alignment: \"50%\",\n    font_family: CAPTION_SETTINGS.fontFamily,\n    font_weight: CAPTION_SETTINGS.fontWeight,\n    font_size: CAPTION_SETTINGS.fontSize,\n    fill_color: CAPTION_SETTINGS.fillColor,\n    stroke_color: CAPTION_SETTINGS.strokeColor,\n    stroke_width: CAPTION_SETTINGS.strokeWidth,\n    shadow_color: CAPTION_SETTINGS.shadowColor,\n    shadow_blur: CAPTION_SETTINGS.shadowBlur\n  });\n}\n\n// ============================================================\n// \ud83d\udce4 OUTPUT\n// ============================================================\n\nconst outputWidth = VIDEO_SETTINGS.usePreviewSize ? VIDEO_SETTINGS.previewWidth : VIDEO_SETTINGS.width;\nconst outputHeight = VIDEO_SETTINGS.usePreviewSize ? VIDEO_SETTINGS.previewHeight : VIDEO_SETTINGS.height;\n\nconst outputScript = {\n  output_format: VIDEO_SETTINGS.outputFormat,\n  width: outputWidth,\n  height: outputHeight,\n  frame_rate: VIDEO_SETTINGS.frameRate,\n  elements: elements,\n  \n  _debug: {\n    version: \"v23.0-stepped-flash\",\n    fix_notes: [\n      \"FIXED: Flash now uses SEQUENTIAL COMPOSITIONS on same track\",\n      \"Each composition has rgba opacity baked into fill_color\",\n      \"No animations needed - stepped opacity creates smooth fade-out\",\n      \"Compositions with empty elements[] act as solid color overlays\",\n      \"Zoom animation uses back-out easing for punch feel\"\n    ],\n    total_beats: STORYBOARD.length,\n    overlay_transitions: overlayTransitionCount,\n    ai_broll_clips: Object.keys(AI_BROLL_URLS).length,\n    avatar_duration: ACTUAL_AVATAR_DURATION,\n    concept_type: conceptType,\n    \n    // INTRO DEBUG\n    intro_effect: {\n      enabled: INTRO_EFFECT.enabled,\n      flash_steps_added: introFlashCount,\n      zoom_applied: introZoomApplied,\n      flash_config: INTRO_EFFECT.flash.enabled ? {\n        step_count: INTRO_EFFECT.flash.steps.length,\n        total_duration: INTRO_EFFECT.flash.steps.reduce((sum, s) => Math.max(sum, s.time + s.duration), 0),\n        approach: \"sequential compositions with rgba opacity\"\n      } : null,\n      zoom_config: INTRO_EFFECT.zoom.enabled ? {\n        start_scale: INTRO_EFFECT.zoom.startScale,\n        end_scale: INTRO_EFFECT.zoom.endScale,\n        duration: INTRO_EFFECT.zoom.duration,\n        easing: INTRO_EFFECT.zoom.easing\n      } : null\n    },\n    \n    layouts_available: Object.keys(lib.layouts || {}),\n    transitions_available: Object.keys(lib.transitions || {}),\n    broll_corrections_applied: brollDurationCorrections.length\n  }\n};\n\nif (ACTUAL_AVATAR_DURATION && typeof ACTUAL_AVATAR_DURATION === 'number') {\n  outputScript.duration = ACTUAL_AVATAR_DURATION;\n}\n\nreturn [{ json: outputScript }];"
      },
      "typeVersion": 2
    },
    {
      "id": "0c129bf6-6116-4c4f-b692-6c3091a6512a",
      "name": "Wait for Avatar",
      "type": "n8n-nodes-base.wait",
      "position": [
        4384,
        1744
      ],
      "parameters": {
        "amount": 45
      },
      "typeVersion": 1.1
    },
    {
      "id": "9085960a-9cac-4432-a200-76e915320c5e",
      "name": "Shorts Trigger",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        1072,
        1664
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    },
    {
      "id": "345e3552-e9c6-4cdf-a8df-a23f865898bd",
      "name": "Extract Snippets",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        1664
      ],
      "parameters": {
        "jsCode": "// ============================================================================\n// EXTRACT SHORT FORM SNIPPETS v4.0 - WITH B-ROLL CLIPS\n// ============================================================================\n// CHANGE: Now includes key_moments (4-8 second B-roll clips) from Gemini\n// WHY: AI scriptwriter needs to know what's visually happening on screen\n// to pick timestamps with maximum movement and write accurate descriptions\n// ============================================================================\n\nconst input = $('Shorts Trigger').first().json;\n\n// Get the pre-analyzed data from parent workflow\nconst source = input.source || {};\nconst overview = input.overview || {};\nconst transcript = input.transcript || {};\nconst links = input.links || {};\n\n// NEW: B-roll clips from Gemini visual analysis (4-8 second moments)\nconst brollClips = input.key_moments || [];\nconst visualAnalysis = input.visual_analysis || {};\n\n// Sections now include nested segments[] with sentence-level timestamps\nconst sections = transcript.sections || [];\nconst segments = transcript.segments || [];\nconst bestSectionsForShorts = transcript.best_sections_for_shorts || [];\n\n// Convert sections to key_moments format (for downstream compatibility)\nconst keyMoments = sections\n  .filter(section => section.hook_potential && section.hook_potential !== 'low')\n  .map(section => ({\n    section_index: section.index,\n    timestamp_start: section.start,\n    timestamp_end: section.end,\n    start_formatted: section.start_formatted,\n    end_formatted: section.end_formatted,\n    duration_seconds: section.duration_seconds,\n    description: section.summary,\n    hook_potential: mapHookPotential(section.hook_potential),\n    quote: section.quotable_moment || null,\n    tools_shown: section.key_topics || [],\n    section_title: section.title,\n    section_type: section.section_type,\n    segment_count: section.segment_count || (section.segments ? section.segments.length : 0)\n  }));\n\n// Map hook_potential to our concept types\nfunction mapHookPotential(potential) {\n  if (potential === 'high') return 'bold';\n  if (potential === 'medium') return 'curiosity';\n  return 'pain';\n}\n\n// Use best_sections_for_shorts as best_clips (already identified by AI!)\nconst bestClips = bestSectionsForShorts.map(sectionIndex => {\n  const section = sections[sectionIndex];\n  if (!section) return null;\n  return {\n    section_index: sectionIndex,\n    start: section.start,\n    end: section.end,\n    start_formatted: section.start_formatted,\n    end_formatted: section.end_formatted,\n    duration_seconds: section.duration_seconds,\n    description: section.summary,\n    hook_potential: section.hook_potential,\n    segment_count: section.segment_count || (section.segments ? section.segments.length : 0)\n  };\n}).filter(Boolean);\n\n// If no best_sections identified, pick top 3 high-potential sections\nif (bestClips.length === 0) {\n  const highPotential = sections\n    .filter(s => s.hook_potential === 'high' || s.hook_potential === 'medium')\n    .slice(0, 3);\n  \n  highPotential.forEach(section => {\n    bestClips.push({\n      section_index: section.index,\n      start: section.start,\n      end: section.end,\n      start_formatted: section.start_formatted,\n      end_formatted: section.end_formatted,\n      duration_seconds: section.duration_seconds,\n      description: section.summary,\n      hook_potential: section.hook_potential,\n      segment_count: section.segment_count || (section.segments ? section.segments.length : 0)\n    });\n  });\n}\n\n// ============================================================================\n// ENRICH B-ROLL CLIPS WITH SECTION CONTEXT\n// ============================================================================\n// Match each B-roll clip to its corresponding section for context\n// ============================================================================\n\nconst enrichedBrollClips = brollClips.map((clip, index) => {\n  // Find which section this clip falls into\n  const matchingSection = sections.find(s => \n    clip.start_seconds >= s.start && clip.start_seconds < s.end\n  );\n  \n  return {\n    index: index,\n    start: clip.start,\n    end: clip.end,\n    start_seconds: clip.start_seconds,\n    end_seconds: clip.end_seconds,\n    duration_seconds: (clip.end_seconds || 0) - (clip.start_seconds || 0),\n    app: clip.app,\n    action: clip.action,\n    screen_description: clip.screen_description || null,\n    // Section context\n    section_index: matchingSection ? matchingSection.index : null,\n    section_title: matchingSection ? matchingSection.title : null\n  };\n});\n\nreturn [{\n  json: {\n    // Video metadata\n    video_id: source.video_id,\n    video_name: source.video_name,\n    video_url: source.video_url,\n    duration: source.duration_seconds,\n    duration_formatted: source.duration_formatted,\n    \n    // Pre-analyzed overview (no more re-summarizing!)\n    video_summary: overview.summary,\n    one_liner: overview.one_liner,\n    main_argument: overview.main_argument,\n    target_audience: overview.target_audience,\n    content_style: overview.content_style,\n    tone: overview.tone,\n    key_takeaways: overview.key_takeaways || [],\n    problems_addressed: overview.problems_addressed || [],\n    tools_mentioned: overview.tools_mentioned || [],\n    frameworks_explained: overview.frameworks_explained || [],\n    \n    // Section-based moments (exact timestamps!)\n    key_moments: keyMoments,\n    best_clips: bestClips,\n    \n    // =========================================================================\n    // NEW: B-ROLL CLIPS FROM GEMINI VISUAL ANALYSIS (v4 UPDATE)\n    // 4-8 second clips with high visual movement - use these for body_segments!\n    // =========================================================================\n    broll_clips: enrichedBrollClips,\n    broll_count: enrichedBrollClips.length,\n    visual_analysis: {\n      enabled: visualAnalysis.enabled || brollClips.length > 0,\n      total_clips: brollClips.length,\n      unique_apps: visualAnalysis.unique_apps || [...new Set(brollClips.map(c => c.app).filter(Boolean))],\n      total_broll_time: enrichedBrollClips.reduce((sum, c) => sum + (c.duration_seconds || 0), 0),\n      coverage_percentage: visualAnalysis.coverage_percentage || null\n    },\n    \n    // Main topics\n    main_topics: transcript.main_topics || [],\n    best_sections_for_shorts: bestSectionsForShorts,\n    \n    // =========================================================================\n    // FULL SECTION DATA WITH NESTED SEGMENTS\n    // Each section now contains segments[] array with sentence-level timestamps\n    // =========================================================================\n    sections: sections,\n    \n    // Stats\n    segment_count: transcript.segment_count,\n    section_count: transcript.section_count,\n    \n    // Pass through links for CTAs\n    links: links\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "dddc1e5b-4bfa-476a-a8de-4d565c6727a4",
      "name": "Creatomate Effects Library",
      "type": "n8n-nodes-base.code",
      "position": [
        3488,
        1648
      ],
      "parameters": {
        "jsCode": "// ============================================================\n// CREATOMATE EFFECTS LIBRARY v2.0 - ENHANCED TRANSITIONS\n// ============================================================\n// Place this node BEFORE the AI Video Director node\n// \n// CHANGELOG v2.0:\n// - Added 6 NEW transition effects for high-retention content:\n//   * RGB_GLITCH - Red/Cyan color channel split with position jitter\n//   * ACCENT_FLASH - Brand color flash before white (depth effect)\n//   * GLITCH_BARS - Moving horizontal scan lines (cyan/magenta)\n//   * ZOOM_SHAKE - Flash with scale jitter and position shake\n//   * DOUBLE_FLASH - Quick double-tap flash for punchy moments\n//   * WHIP_PAN - Flash sweeps horizontally across screen\n// - Removed unused transitions: WIPE_LEFT_FAST, WIPE_RIGHT_FAST, WIPE_UP, FADE_QUICK, CUT\n// - Added transition variety guidelines\n//\n// CHANGELOG v1.9:\n// - Added SPLIT_70_30 layout (screen 70% top, avatar 30% bottom)\n// - Added SCREEN_PADDED layout (fullscreen screen recording with centered padding and glow)\n// ============================================================\n\nreturn [{\n  json: {\n    // ============================================================\n    // LAYOUT LIBRARY\n    // ============================================================\n    layouts: {\n      \n      AVATAR_FULLSCREEN: {\n        id: \"AVATAR_FULLSCREEN\",\n        description: \"Avatar fills entire frame - hooks and CTAs ONLY\",\n        avatar: { x: \"50%\", y: \"50%\", width: \"100%\", height: \"100%\" },\n        screen: null,\n        divider_y: null,\n        best_for: [\"hook_snap\", \"cta_close\"],\n        energy: \"high\",\n        restriction: \"ONLY use for first beat (hook_snap) and last beat (cta_close)\"\n      },\n      \n      SCREEN_FULLSCREEN: {\n        id: \"SCREEN_FULLSCREEN\",\n        description: \"AI B-roll fills entire frame edge-to-edge - cinematic moments\",\n        avatar: null,\n        screen: { x: \"50%\", y: \"50%\", width: \"100%\", height: \"100%\" },\n        divider_y: null,\n        is_padded_screen: false,\n        best_for: [\"ai_broll\", \"cinematic_moments\", \"dramatic_reveals\"],\n        energy: \"high\",\n        restriction: \"Use ONLY with broll_type: ai_generated\"\n      },\n      \n      SCREEN_PADDED: {\n        id: \"SCREEN_PADDED\",\n        description: \"Fullscreen screen recording with centered padding and glow - for widescreen B-roll without avatar\",\n        avatar: null,\n        screen: { x: \"50%\", y: \"50%\", width: \"100%\", height: \"100%\" },\n        divider_y: null,\n        is_padded_screen: true,\n        best_for: [\"screen_broll_fullscreen\", \"desktop_recordings\", \"widescreen_demos\", \"detailed_walkthroughs\"],\n        energy: \"medium\",\n        restriction: \"Use ONLY with broll_type: screen\"\n      },\n      \n      SPLIT_50_50: {\n        id: \"SPLIT_50_50\",\n        description: \"Screen 50% top, Avatar 50% bottom - equal split\",\n        avatar: { x: \"50%\", y: \"75%\", width: \"100%\", height: \"50%\" },\n        screen: { x: \"50%\", y: \"25%\", width: \"100%\", height: \"50%\" },\n        divider_y: \"50%\",\n        best_for: [\"balanced_demos\", \"conversational_teaching\", \"screen_with_presence\"],\n        energy: \"medium\"\n      },\n      \n      SPLIT_60_40: {\n        id: \"SPLIT_60_40\",\n        description: \"Screen 60% top, Avatar 40% bottom - screen-dominant\",\n        avatar: { x: \"50%\", y: \"80%\", width: \"100%\", height: \"40%\" },\n        screen: { x: \"50%\", y: \"30%\", width: \"100%\", height: \"60%\" },\n        divider_y: \"60%\",\n        best_for: [\"standard_demos\", \"code_walkthroughs\", \"body_flash\", \"transitions\"],\n        energy: \"medium\"\n      },\n      \n      SPLIT_70_30: {\n        id: \"SPLIT_70_30\",\n        description: \"Screen 70% top, Avatar 30% bottom - maximum screen focus\",\n        avatar: { x: \"50%\", y: \"85%\", width: \"100%\", height: \"30%\" },\n        screen: { x: \"50%\", y: \"35%\", width: \"100%\", height: \"70%\" },\n        divider_y: \"70%\",\n        best_for: [\"detailed_demos\", \"code_focus\", \"body_demo\", \"screen_heavy_content\", \"complex_ui\"],\n        energy: \"medium\"\n      }\n    },\n\n    // ============================================================\n    // TRANSITION LIBRARY\n    // ============================================================\n    transitions: {\n      \n      // ========================================\n      // \ud83d\udd25 FLASH - White flash overlay effect\n      // ========================================\n      FLASH: {\n        id: \"FLASH\",\n        type: \"flash\",\n        description: \"\u26a1 PUNCHY white flash - 100% opacity with hold\",\n        duration: 0.25,\n        color: \"#FFFFFF\",\n        opacity_keyframes: [\n          { time: \"0 s\", value: \"0%\" },\n          { time: \"0.02 s\", value: \"100%\" },\n          { time: \"0.08 s\", value: \"100%\" },\n          { time: \"0.25 s\", value: \"0%\", easing: \"quadratic-out\" }\n        ],\n        energy: \"highest\",\n        best_for: [\"snap_words\", \"major_reveals\", \"layout_changes\"],\n        frequency_target: \"3-4 per video (mix with other transitions)\"\n      },\n      \n      // ========================================\n      // \ud83c\udf08 RGB_GLITCH - Color channel split\n      // ========================================\n      RGB_GLITCH: {\n        id: \"RGB_GLITCH\",\n        type: \"rgb_glitch\",\n        description: \"\ud83c\udf08 Red/Cyan color split with position jitter - tech feel\",\n        duration: 0.25,\n        layers: [\n          {\n            color: \"#FF0000\",\n            opacity_keyframes: [\n              { time: \"0 s\", value: \"0%\" },\n              { time: \"0.02 s\", value: \"50%\" },\n              { time: \"0.06 s\", value: \"35%\" },\n              { time: \"0.12 s\", value: \"0%\" }\n            ],\n            x_keyframes: [\n              { time: \"0 s\", value: \"47%\" },\n              { time: \"0.04 s\", value: \"53%\" },\n              { time: \"0.08 s\", value: \"49%\" },\n              { time: \"0.12 s\", value: \"50%\" }\n            ]\n          },\n          {\n            color: \"#00FFFF\",\n            opacity_keyframes: [\n              { time: \"0 s\", value: \"0%\" },\n              { time: \"0.02 s\", value: \"50%\" },\n              { time: \"0.06 s\", value: \"35%\" },\n              { time: \"0.12 s\", value: \"0%\" }\n            ],\n            x_keyframes: [\n              { time: \"0 s\", value: \"53%\" },\n              { time: \"0.04 s\", value: \"47%\" },\n              { time: \"0.08 s\", value: \"51%\" },\n              { time: \"0.12 s\", value: \"50%\" }\n            ]\n          }\n        ],\n        flash_follows: true,\n        energy: \"highest\",\n        best_for: [\"tech_content\", \"ai_reveals\", \"pattern_interrupts\"],\n        frequency_target: \"2-3 per video\"\n      },\n      \n      // ========================================\n      // \ud83c\udfa8 ACCENT_FLASH - Brand color flash\n      // ========================================\n      ACCENT_FLASH: {\n        id: \"ACCENT_FLASH\",\n        type: \"accent_flash\",\n        description: \"\ud83c\udfa8 Brand color flash before white - adds depth\",\n        duration: 0.27,\n        accent_color: \"#FF4444\",\n        accent_duration: 0.08,\n        accent_opacity_keyframes: [\n          { time: \"0 s\", value: \"0%\" },\n          { time: \"0.02 s\", value: \"70%\" },\n          { time: \"0.08 s\", value: \"0%\", easing: \"quadratic-out\" }\n        ],\n        white_delay: 0.03,\n        white_opacity_keyframes: [\n          { time: \"0 s\", value: \"0%\" },\n          { time: \"0.02 s\", value: \"100%\" },\n          { time: \"0.08 s\", value: \"100%\" },\n          { time: \"0.22 s\", value: \"0%\", easing: \"quadratic-out\" }\n        ],\n        energy: \"highest\",\n        best_for: [\"brand_moments\", \"important_reveals\", \"split_layout_entries\"],\n        frequency_target: \"2-3 per video\"\n      },\n      \n      // ========================================\n      // \ud83d\udcfa GLITCH_BARS - Scan line effect\n      // ========================================\n      GLITCH_BARS: {\n        id: \"GLITCH_BARS\",\n        type: \"glitch_bars\",\n        description: \"\ud83d\udcfa Moving horizontal scan lines - retro tech feel\",\n        duration: 0.27,\n        bars: [\n          {\n            color: \"#00FFFF\",\n            height: \"6%\",\n            opacity_keyframes: [\n              { time: \"0 s\", value: \"60%\" },\n              { time: \"0.1 s\", value: \"0%\" }\n            ],\n            y_keyframes: [\n              { time: \"0 s\", value: \"15%\" },\n              { time: \"0.05 s\", value: \"55%\" },\n              { time: \"0.1 s\", value: \"85%\" }\n            ]\n          },\n          {\n            color: \"#FF00FF\",\n            height: \"4%\",\n            opacity_keyframes: [\n              { time: \"0 s\", value: \"50%\" },\n              { time: \"0.1 s\", value: \"0%\" }\n            ],\n            y_keyframes: [\n              { time: \"0 s\", value: \"75%\" },\n              { time: \"0.05 s\", value: \"35%\" },\n              { time: \"0.1 s\", value: \"10%\" }\n            ]\n          }\n        ],\n        flash_follows: true,\n        energy: \"high\",\n        best_for: [\"tech_transitions\", \"screen_reveals\", \"variety\"],\n        frequency_target: \"1-2 per video\"\n      },\n      \n      // ========================================\n      // \ud83d\udca5 ZOOM_SHAKE - Flash with jitter\n      // ========================================\n      ZOOM_SHAKE: {\n        id: \"ZOOM_SHAKE\",\n        type: \"zoom_shake\",\n        description: \"\ud83d\udca5 Flash with scale jitter and position shake - impact feel\",\n        duration: 0.3,\n        color: \"#FFFFFF\",\n        opacity_keyframes: [\n          { time: \"0 s\", value: \"0%\" },\n          { time: \"0.02 s\", value: \"100%\" },\n          { time: \"0.1 s\", value: \"85%\" },\n          { time: \"0.3 s\", value: \"0%\", easing: \"quadratic-out\" }\n        ],\n        scale_keyframes: [\n          { time: \"0 s\", value: \"100%\" },\n          { time: \"0.04 s\", value: \"108%\" },\n          { time: \"0.08 s\", value: \"96%\" },\n          { time: \"0.12 s\", value: \"103%\" },\n          { time: \"0.2 s\", value: \"99%\" },\n          { time: \"0.3 s\", value: \"100%\" }\n        ],\n        x_keyframes: [\n          { time: \"0 s\", value: \"50%\" },\n          { time: \"0.05 s\", value: \"51%\" },\n          { time: \"0.1 s\", value: \"49%\" },\n          { time: \"0.15 s\", value: \"50.5%\" },\n          { time: \"0.2 s\", value: \"49.5%\" },\n          { time: \"0.3 s\", value: \"50%\" }\n        ],\n        energy: \"highest\",\n        best_for: [\"major_impacts\", \"ai_broll_entries\", \"emphasis_moments\"],\n        frequency_target: \"1-2 per video\"\n      },\n      \n      // ========================================\n      // \u26a1\u26a1 DOUBLE_FLASH - Quick double-tap\n      // ========================================\n      DOUBLE_FLASH: {\n        id: \"DOUBLE_FLASH\",\n        type: \"double_flash\",\n        description: \"\u26a1\u26a1 Quick double-tap flash - extra punchy\",\n        duration: 0.18,\n        color: \"#FFFFFF\",\n        opacity_keyframes: [\n          { time: \"0 s\", value: \"0%\" },\n          { time: \"0.02 s\", value: \"100%\" },\n          { time: \"0.05 s\", value: \"0%\" },\n          { time: \"0.08 s\", value: \"85%\" },\n          { time: \"0.18 s\", value: \"0%\", easing: \"quadratic-out\" }\n        ],\n        energy: \"highest\",\n        best_for: [\"snap_words\", \"double_emphasis\", \"rhythm_moments\"],\n        frequency_target: \"1-2 per video\"\n      },\n      \n      // ========================================\n      // \ud83c\udf0a WHIP_PAN - Horizontal sweep\n      // ========================================\n      WHIP_PAN: {\n        id: \"WHIP_PAN\",\n        type: \"whip_pan\",\n        description: \"\ud83c\udf0a Flash sweeps horizontally - directional energy\",\n        duration: 0.15,\n        color: \"#FFFFFF\",\n        width: \"120%\",\n        opacity_keyframes: [\n          { time: \"0 s\", value: \"0%\" },\n          { time: \"0.03 s\", value: \"100%\" },\n          { time: \"0.12 s\", value: \"90%\" },\n          { time: \"0.15 s\", value: \"0%\" }\n        ],\n        x_keyframes: [\n          { time: \"0 s\", value: \"-10%\" },\n          { time: \"0.08 s\", value: \"50%\" },\n          { time: \"0.15 s\", value: \"110%\" }\n        ],\n        direction: \"left_to_right\",\n        energy: \"high\",\n        best_for: [\"progression\", \"before_after\", \"scene_changes\"],\n        frequency_target: \"1-2 per video\"\n      },\n      \n      // ========================================\n      // \u2702\ufe0f GLITCH_CUT - Micro-scale jitter\n      // ========================================\n      GLITCH_CUT: {\n        id: \"GLITCH_CUT\",\n        type: \"scale\",\n        description: \"\u2702\ufe0f Cut with aggressive micro-scale jitter\",\n        duration: 0.1,\n        start_scale: \"108%\",\n        end_scale: \"100%\",\n        easing: \"linear\",\n        energy: \"high\",\n        best_for: [\"tech_content\", \"quick_cuts\", \"variety\"],\n        frequency_target: \"2-3 per video\"\n      },\n      \n      // ========================================\n      // SCALE TRANSITIONS\n      // ========================================\n      SCALE_PUNCH: {\n        id: \"SCALE_PUNCH\",\n        type: \"scale\",\n        description: \"HEAVY punchy scale burst with overshoot\",\n        duration: 0.18,\n        start_scale: \"130%\",\n        end_scale: \"100%\",\n        easing: \"back-out\",\n        energy: \"high\",\n        best_for: [\"ai_broll_entry\", \"reveals\", \"emphasis\"]\n      },\n      \n      SCALE_POP: {\n        id: \"SCALE_POP\",\n        type: \"scale\",\n        description: \"Quick scale pop - punchy but softer than PUNCH\",\n        duration: 0.2,\n        start_scale: \"118%\",\n        end_scale: \"100%\",\n        easing: \"back-out\",\n        energy: \"high\",\n        best_for: [\"secondary_beats\", \"detail_reveals\", \"split_entries\"]\n      },\n      \n      SCALE_BOUNCE: {\n        id: \"SCALE_BOUNCE\",\n        type: \"scale\",\n        description: \"Elastic bounce - playful feel\",\n        duration: 0.3,\n        start_scale: \"125%\",\n        end_scale: \"100%\",\n        easing: \"elastic-out\",\n        energy: \"high\",\n        best_for: [\"wins\", \"positive_moments\", \"money_mentions\"]\n      },\n      \n      // ========================================\n      // SLIDE TRANSITIONS\n      // ========================================\n      SLIDE_UP_FAST: {\n        id: \"SLIDE_UP_FAST\",\n        type: \"slide\",\n        description: \"Fast slide up with overshoot\",\n        duration: 0.2,\n        distance: \"15%\",\n        direction: \"90\u00b0\",\n        easing: \"back-out\",\n        fade: false,\n        energy: \"high\",\n        best_for: [\"avatar_entries\", \"new_sections\"]\n      },\n      \n      SLIDE_DOWN_FAST: {\n        id: \"SLIDE_DOWN_FAST\",\n        type: \"slide\",\n        description: \"Fast slide down with overshoot\",\n        duration: 0.2,\n        distance: \"15%\",\n        direction: \"270\u00b0\",\n        easing: \"back-out\",\n        fade: false,\n        energy: \"high\",\n        best_for: [\"screen_reveals\", \"split_screen_entries\"]\n      },\n      \n      // ========================================\n      // FADE (CTA ONLY)\n      // ========================================\n      FADE: {\n        id: \"FADE\",\n        type: \"fade\",\n        description: \"Standard crossfade - CTA ONLY\",\n        duration: 0.25,\n        energy: \"low\",\n        best_for: [\"cta_entry\"],\n        note: \"Max 1 per video - ONLY for final CTA beat\"\n      }\n    },\n\n    // ============================================================\n    // SCREEN MOTION LIBRARY\n    // ============================================================\n    screen_motions: {\n      \n      SLOW_ZOOM_IN: {\n        id: \"SLOW_ZOOM_IN\",\n        type: \"zoom\",\n        description: \"Slowly zooms in\",\n        start_scale: \"100%\",\n        end_scale: \"112%\",\n        easing: \"linear\",\n        best_for: [\"detail_reveals\", \"default_motion\"],\n        min_duration: 3\n      },\n      \n      SLOW_ZOOM_OUT: {\n        id: \"SLOW_ZOOM_OUT\",\n        type: \"zoom\",\n        description: \"Slowly zooms out\",\n        start_scale: \"115%\",\n        end_scale: \"100%\",\n        easing: \"linear\",\n        best_for: [\"dashboard_overviews\", \"big_picture\"],\n        min_duration: 3\n      },\n      \n      DRAMATIC_ZOOM_IN: {\n        id: \"DRAMATIC_ZOOM_IN\",\n        type: \"zoom\",\n        description: \"Fast zoom in - dramatic emphasis\",\n        start_scale: \"100%\",\n        end_scale: \"120%\",\n        easing: \"quadratic-in\",\n        best_for: [\"emphasis_moments\"],\n        min_duration: 2\n      },\n      \n      STATIC: {\n        id: \"STATIC\",\n        type: \"static\",\n        description: \"No movement - for beats under 3 seconds\",\n        best_for: [\"quick_flashes\"],\n        max_duration: 3\n      }\n    },\n\n    // ============================================================\n    // AVATAR ANIMATION LIBRARY\n    // ============================================================\n    avatar_animations: {\n      \n      ZOOM_DRAMATIC: {\n        id: \"ZOOM_DRAMATIC\",\n        type: \"scale\",\n        description: \"Dramatic zoom entrance - punchy\",\n        start_scale: \"115%\",\n        end_scale: \"100%\",\n        duration: 0.25,\n        easing: \"back-out\",\n        best_for: [\"hook_snap\", \"major_emphasis\"]\n      },\n      \n      SCALE_ENTRANCE: {\n        id: \"SCALE_ENTRANCE\",\n        type: \"scale\",\n        description: \"Scale entrance with bounce\",\n        start_scale: \"90%\",\n        end_scale: \"100%\",\n        duration: 0.25,\n        easing: \"back-out\",\n        best_for: [\"segment_starts\", \"re_entering_frame\"]\n      },\n      \n      SLIDE_IN_UP: {\n        id: \"SLIDE_IN_UP\",\n        type: \"slide\",\n        description: \"Slides in from below with bounce\",\n        direction: \"up\",\n        distance: \"10%\",\n        duration: 0.25,\n        easing: \"back-out\",\n        best_for: [\"energetic_entrances\", \"split_layout_avatar\"]\n      },\n      \n      NONE: {\n        id: \"NONE\",\n        type: \"none\",\n        description: \"No animation\",\n        best_for: [\"continuations\", \"same_layout\"]\n      }\n    },\n\n    // ============================================================\n    // TEXT OVERLAY STYLES\n    // ============================================================\n    text_styles: {\n      \n      HOOK_TEXT: {\n        id: \"HOOK_TEXT\",\n        description: \"Large white text with black stroke\",\n        font_family: \"Montserrat\",\n        font_weight: 900,\n        font_size: \"7.5 vmin\",\n        fill_color: \"#FFFFFF\",\n        stroke_color: \"#000000\",\n        stroke_width: \"0.8 vmin\",\n        shadow_color: \"rgba(0,0,0,0.85)\",\n        shadow_blur: \"1.2 vmin\",\n        position: { x: \"50%\", y: \"78%\" },\n        best_for: [\"hook_overlays\"]\n      },\n\n      CTA_BOX_RED: {\n        id: \"CTA_BOX_RED\",\n        description: \"Red background, white text\",\n        font_family: \"Montserrat\",\n        font_weight: 800,\n        font_size: \"6.5 vmin\",\n        fill_color: \"#FFFFFF\",\n        background_color: \"#FF0000\",\n        background_x_padding: \"5%\",\n        background_y_padding: \"3%\",\n        background_border_radius: \"8%\",\n        position: { x: \"50%\", y: \"80%\" },\n        best_for: [\"urgent_ctas\"]\n      },\n      \n      CTA_BOX_ACCENT: {\n        id: \"CTA_BOX_ACCENT\",\n        description: \"Accent-colored background\",\n        font_family: \"Montserrat\",\n        font_weight: 800,\n        font_size: \"6.5 vmin\",\n        fill_color: \"#000000\",\n        background_color: \"{{ACCENT_COLOR}}\",\n        background_x_padding: \"5%\",\n        background_y_padding: \"3%\",\n        background_border_radius: \"8%\",\n        position: { x: \"50%\", y: \"80%\" },\n        best_for: [\"branded_ctas\"]\n      },\n      \n      CTA_MINIMAL: {\n        id: \"CTA_MINIMAL\",\n        description: \"White text, heavy stroke\",\n        font_family: \"Montserrat\",\n        font_weight: 800,\n        font_size: \"6.5 vmin\",\n        fill_color: \"#FFFFFF\",\n        stroke_color: \"#000000\",\n        stroke_width: \"0.6 vmin\",\n        shadow_color: \"rgba(0,0,0,0.9)\",\n        shadow_blur: \"1 vmin\",\n        position: { x: \"50%\", y: \"80%\" },\n        best_for: [\"soft_ctas\"]\n      }\n    },\n\n    // ============================================================\n    // EASING FUNCTIONS\n    // ============================================================\n    easings: {\n      linear: { id: \"linear\", description: \"Constant speed\" },\n      \"quadratic-in\": { id: \"quadratic-in\", description: \"Slow start, fast end\" },\n      \"quadratic-out\": { id: \"quadratic-out\", description: \"Fast start, slow end\" },\n      \"quadratic-in-out\": { id: \"quadratic-in-out\", description: \"Smooth both ends\" },\n      \"cubic-in-out\": { id: \"cubic-in-out\", description: \"Smoother both ends\" },\n      \"back-out\": { id: \"back-out\", description: \"Overshoot then settle - PUNCHY\" },\n      \"elastic-out\": { id: \"elastic-out\", description: \"Bouncy spring effect\" }\n    },\n\n    // ============================================================\n    // ACCENT COLORS\n    // ============================================================\n    accent_colors: {\n      pain: \"#FF4444\",\n      curiosity: \"#FFD700\",\n      transformation: \"#00E676\",\n      bold: \"#00E676\"\n    },\n\n    // ============================================================\n    // AUDIO TRACKS\n    // ============================================================\n    audio_tracks: {\n      1: { name: \"Technology Upbeat\", file: \"technology_upbeat.mp3\", energy: \"HIGH\", best_for: [\"fast_demos\", \"tech_content\"] },\n      3: { name: \"Cinematic Epic\", file: \"cinematic_epic.mp3\", energy: \"HIGH\", best_for: [\"big_reveals\", \"transformation\"] },\n      5: { name: \"Dark Suspense\", file: \"dark_suspense.mp3\", energy: \"MEDIUM\", best_for: [\"pain_concepts\"] },\n      7: { name: \"Minimal Electronic\", file: \"minimal_electronic.mp3\", energy: \"LOW\", best_for: [\"curiosity_concepts\", \"teaching\"] },\n      8: { name: \"Motivational\", file: \"motivational.mp3\", energy: \"MEDIUM-HIGH\", best_for: [\"transformation_concepts\"] },\n      9: { name: \"Futuristic Technology\", file: \"futuristic_technology.mp3\", energy: \"MEDIUM\", best_for: [\"tech_content\", \"innovation\"] }\n    },\n\n    // ============================================================\n    // USAGE GUIDELINES\n    // ============================================================\n    guidelines: {\n      \n      transitions: {\n        variety_rule: \"NEVER use the same transition type 2x in a row - always vary!\",\n        flash_rule: \"Standard FLASH: 3-4 per video (not every transition)\",\n        rgb_glitch_rule: \"RGB_GLITCH for tech moments and AI reveals (2-3 per video)\",\n        accent_flash_rule: \"ACCENT_FLASH for brand moments and split entries (2-3 per video)\",\n        glitch_bars_rule: \"GLITCH_BARS for retro tech feel (1-2 per video)\",\n        zoom_shake_rule: \"ZOOM_SHAKE for major impacts (1-2 per video)\",\n        double_flash_rule: \"DOUBLE_FLASH for extra punchy moments (1-2 per video)\",\n        whip_pan_rule: \"WHIP_PAN for progression/scene changes (1-2 per video)\",\n        fade_rule: \"FADE only for CTA (max 1 per video)\",\n        recommended_mix: \"For a 30s video with ~10 transitions: 3 FLASH, 2 RGB_GLITCH, 2 ACCENT_FLASH, 1 GLITCH_BARS, 1 ZOOM_SHAKE, 1 FADE (CTA)\"\n      },\n      \n      layouts: {\n        available: [\"AVATAR_FULLSCREEN\", \"SCREEN_FULLSCREEN\", \"SCREEN_PADDED\", \"SPLIT_50_50\", \"SPLIT_60_40\", \"SPLIT_70_30\"],\n        no_consecutive_repeat: \"Never use same layout 2x in a row\",\n        avatar_fullscreen_rule: \"AVATAR_FULLSCREEN ONLY for first beat (hook_snap) and last beat (cta_close) - NEVER for middle beats\",\n        broll_layout_mapping: {\n          ai_generated: \"SCREEN_FULLSCREEN (edge-to-edge cinematic, no padding)\",\n          screen_fullscreen: \"SCREEN_PADDED (centered with glow/padding for widescreen recordings)\",\n          screen_split: \"SPLIT_50_50, SPLIT_60_40, or SPLIT_70_30 (screen top, avatar bottom)\",\n          none_first_last: \"AVATAR_FULLSCREEN (ONLY for first and last beats)\"\n        },\n        middle_beat_options: \"For middle beats, use ONLY: SCREEN_FULLSCREEN, SCREEN_PADDED, SPLIT_50_50, SPLIT_60_40, SPLIT_70_30\"\n      },\n      \n      timing: {\n        max_beat_length: \"4 seconds (HARD LIMIT - NEVER EXCEED)\",\n        target_beat_length: \"2.5-3.5 seconds\",\n        min_beat_length: \"2 seconds\"\n      },\n      \n      broll_rules: {\n        none_restriction: \"broll_type 'none' is ONLY valid for AVATAR_FULLSCREEN layouts (first/last beats)\",\n        split_requirement: \"SPLIT layouts MUST have broll_type 'screen' with valid broll_index and timestamps\",\n        screen_padded_requirement: \"SCREEN_PADDED MUST have broll_type 'screen' with valid broll_index and timestamps\",\n        screen_fullscreen_requirement: \"SCREEN_FULLSCREEN MUST have broll_type 'ai_generated' with valid ai_broll_index\"\n      },\n      \n      element_animations: {\n        split_entry: \"When entering split layout, avatar slides up (SLIDE_IN_UP) and screen slides down (SLIDE_DOWN_FAST)\",\n        ai_broll_entry: \"AI B-roll should enter with SCALE_PUNCH (125-130% start)\",\n        avatar_fullscreen_entry: \"Avatar fullscreen can use ZOOM_DRAMATIC or GLITCH_CUT\"\n      }\n    },\n\n    // ============================================================\n    // SNAP WORDS (sync with transitions)\n    // ============================================================\n    snap_words: [\n      \"Watch THIS\",\n      \"And BOOM\",\n      \"Right here\",\n      \"Here's the thing\",\n      \"See this?\",\n      \"Now watch\",\n      \"Look\",\n      \"THIS is\",\n      \"THAT'S when\",\n      \"Until now\",\n      \"But here's\",\n      \"The secret?\",\n      \"STOP\"\n    ],\n\n    // ============================================================\n    // TRANSITION TYPE REFERENCE (for Template Builder)\n    // ============================================================\n    transition_types: {\n      flash: [\"FLASH\", \"DOUBLE_FLASH\"],\n      rgb: [\"RGB_GLITCH\"],\n      accent: [\"ACCENT_FLASH\"],\n      glitch: [\"GLITCH_BARS\", \"GLITCH_CUT\"],\n      shake: [\"ZOOM_SHAKE\"],\n      directional: [\"WHIP_PAN\", \"SLIDE_UP_FAST\", \"SLIDE_DOWN_FAST\"],\n      scale: [\"SCALE_PUNCH\", \"SCALE_POP\", \"SCALE_BOUNCE\"],\n      soft: [\"FADE\"]\n    }\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "ffeefe34-afb7-4f15-a3da-eae61bc17191",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        3712,
        1744
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "7e25fb9d-c7af-4382-a28d-7892d8f6bf8a",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1520,
        1664
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9895773e-7937-4936-be0c-2b144039f5df",
              "name": "User Prompt",
              "type": "string",
              "value": "==VIDEO ANALYSIS:\n\n## Overview\n- **Summary**: {{ $json.video_summary }}\n- **One-liner**: {{ $json.one_liner }}\n- **Target Audience**: {{ $json.target_audience }}\n\n## Key Takeaways\n{{ $json.key_takeaways.map((t, i) => `${i+1}. ${t}`).join('\\n') }}\n\n## Problems Addressed\n{{ $json.problems_addressed.map((p, i) => `${i+1}. ${p}`).join('\\n') }}\n\n---\n\n## \ud83c\udfac AVAILABLE B-ROLL CLIPS\n\nThese are visual moments you can use as SUPPORTING VISUALS (not to be described in narration).\n\n{{ $json.broll_clips && $json.broll_clips.length > 0 ? $json.broll_clips.map((clip, idx) => `\n**[${idx}]** Start: ${clip.start_seconds}s | End: ${clip.end_seconds}s | Duration: ${clip.duration_seconds}s\n- App: ${clip.app}\n- Shows: ${clip.screen_description || clip.action}\n- Good for topics about: ${clip.app.includes('n8n') ? 'automation, workflows, integration' : clip.app.includes('Code') || clip.app.includes('Cursor') ? 'building, coding, development' : clip.app.includes('Chrome') ? 'tools, software, dashboards' : 'general tech topics'}\n`).join('\\n') : 'No B-roll clips available.' }}\n\n---\n\n## SECTION SUMMARIES\n\n{{ $json.sections.map(s => `\n**Section ${s.index}: ${s.title}**\n${s.summary}\n`).join('\\n') }}\n\n---\n\n## YOUR TASK\n\nCreate 3 concepts with full storyboards.\n\nFor each body segment:\n1. Write narration about a TOPIC (a point, insight, or claim)\n2. Select B-roll that VISUALLY SUPPORTS that topic\n3. The avatar should NOT reference or describe the B-roll\n\nRemember:\n- No \"watch this\", \"look at this\", \"see how\", etc.\n- The B-roll just plays underneath while the avatar makes their point\n- Speech rules only apply to narration (numbers as words, no contractions)\n- Timestamps are normal numbers"
            },
            {
              "id": "d1608e4e-8a30-47ef-98da-b24180553262",
              "name": "System Prompt",
              "type": "string",
              "value": "=# Short-Form Content Strategist System Prompt v2.6\n\nYou are a viral short-form content strategist for @adamgoodyer, an A-I educator and Top 1% Upwork freelancer.\n\n---\n\n## BRAND POSITIONING\n\nAdam is the \"Anti-Guru Technical Educator\" \u2014 a real practitioner who shows the work, not just talks about it.\n\n**Target Audience (TOP OF FUNNEL):** \nPeople who are curious about A-I and want to understand how to actually use it. They're NOT developers or technical experts yet. They're:\n- Beginners wanting to learn A-I skills from scratch\n- People overwhelmed by all the new A-I tools launching\n- Curious professionals wondering how A-I affects their work\n- Side hustlers looking for ways to use A-I to make money\n\n**What They Want:**\n- \"What tools should I actually use?\"\n- \"How do I get started with this stuff?\"\n- \"What's new in A-I this week?\"\n- \"Show me something cool I can try right now\"\n\n**Voice:** Direct, conversational, zero fluff. Like explaining something cool to a smart friend over coffee. Think excited older brother sharing a discovery, not professor lecturing.\n\n---\n\n## CRITICAL: WRITING STYLE\n\nYour scripts must sound like **Nick Saraev and Nate Herk** \u2014 conversational, punchy, easy to follow.\n\n### STUDY THESE PATTERNS\n\n**Good hooks (from top performers):**\n- \"Here's how to make YouTube shorts that post themselves, step by step.\"\n- \"Have you ever noticed that ChatGPT is pretty much just a yes man?\"\n- \"While everybody's been obsessing over ChatGPT and Cursor, Google silently released ten free A-I coding tools.\"\n- \"I built a system where all you do is drop in a product photo...\"\n- \"Most people are still manually doing X. - Here's what I do instead.\"\n\n**What makes them work:**\n- Start mid-thought (no \"Hey guys\" or \"In this video\")\n- Create immediate curiosity or call out a relatable frustration\n- Specific, not vague (\"ten free tools\" not \"some tools\")\n- Conversational contractions (don't, it's, that's, here's)\n\n### SENTENCE STRUCTURE\n\nWrite like you talk. Short sentences. Punchy delivery.\n\n**BAD (too formal, too long):**\n\"The implementation of automated systems within your business infrastructure can significantly reduce the amount of time that you spend on repetitive administrative tasks.\"\n\n**GOOD (conversational, punchy):**\n\"You're probably spending five hours a week on stuff that should take five minutes. - Here's how to fix that.\"\n\n**BAD (robotic, no contractions):**\n\"It is not difficult. You do not need to code. That is the whole point.\"\n\n**GOOD (natural speech):**\n\"It's not hard. - You don't need to code. - That's the whole point.\"\n\n### THE \"FRIEND EXPLAINING\" TEST\n\nBefore finalizing any script, ask: \"Would I actually say this to a friend?\"\n\nIf it sounds like a corporate video or a textbook, rewrite it.\n\n---\n\n## ACCESSIBILITY: WRITE FOR SIXTH GRADERS\n\n**Scripts must be understood by a smart twelve-year-old.** This is critical for top-of-funnel content. If your audience needs to Google words to understand you, you've lost them.\n\n### THE SIXTH GRADE RULE\n\nBefore any sentence makes it into the script, ask: \"Would a sixth grader get this?\"\n\n| Complex Version | Sixth Grade Version |\n|----------------|---------------------|\n| \"Leverage A-I to optimize your workflow efficiency\" | \"Use A-I to get stuff done faster\" |\n| \"This tool facilitates seamless integration between platforms\" | \"This tool connects your apps automatically\" |\n| \"Implement an automated lead generation system\" | \"Build something that finds customers for you\" |\n| \"The A-P-I endpoints handle asynchronous data processing\" | \"It grabs your data and does the work in the background\" |\n\n### RULES FOR SIMPLE LANGUAGE\n\n1. **One idea per sentence**\n   - BAD: \"This tool connects to your email, pulls the data, analyzes it with A-I, and sends you a summary every morning.\"\n   - GOOD: \"This tool reads your emails. - Then A-I picks out the important stuff. - You get a summary every morning.\"\n\n2. **Use words everyone knows**\n   - \"deploy\" \u2192 \"set up\" or \"launch\"\n   - \"configure\" \u2192 \"set up\"\n   - \"integrate\" \u2192 \"connect\"\n   - \"leverage\" \u2192 \"use\"\n   - \"optimize\" \u2192 \"make better\" or \"speed up\"\n   - \"implement\" \u2192 \"build\" or \"add\"\n   - \"utilize\" \u2192 \"use\"\n   - \"facilitate\" \u2192 \"help\" or \"make easier\"\n\n3. **Explain tools by what they DO, not what they ARE**\n   - BAD: \"n-eight-n is a workflow automation platform\"\n   - GOOD: \"n-eight-n connects all your apps and makes them work together automatically\"\n\n4. **Name specific tools whenever possible**\n   - BAD: \"You can use an A-I writing tool\"\n   - GOOD: \"You can use Claude or ChatGPT\"\n   - BAD: \"Connect it to your automation platform\"\n   - GOOD: \"Connect it to n-eight-n or Make\"\n\n5. **Focus on outcomes people care about**\n   - Save time\n   - Make money\n   - Look smarter\n   - Get ahead of others\n   - Stop doing boring stuff manually\n\n### THE FRIEND TEST\n\nRead your script out loud. Does it sound like you're talking to a friend at a coffee shop? Or does it sound like a LinkedIn post? If it's the latter, rewrite it.\n\n---\n\n## SPEECH RULES FOR A-I AVATAR (HeyGen)\n\nThese rules ensure the A-I avatar (HeyGen) pronounces everything correctly and sounds natural.\n\n### PAUSE MARKERS (CRITICAL)\n\n**Use \" - \" (space dash space) between EVERY sentence.** This creates natural pauses that make the avatar sound human, not robotic.\n\n**Format ALL narration with \" - \" between sentences.**\n\n**BAD (no pause markers - sounds rushed and robotic):**\n\"Most people slap a prompt into some A-I tool and hope the whole page just shows up. That never works. You get blurry images, broken layouts, weird animations.\"\n\n**GOOD (pause markers between every sentence - sounds natural):**\n\"Most people slap a prompt into some A-I tool and hope the whole page just shows up. - That never works. - You get blurry images, broken layouts, weird animations.\"\n\n**WHEN TO USE \" - \" PAUSE MARKERS:**\n- Between EVERY sentence without exception\n- After questions (give viewer time to think)\n- Before revealing a solution or answer\n- Between steps in a process\n\n**ADDITIONAL LINE BREAKS FOR MAJOR TRANSITIONS:**\nIn addition to \" - \" between sentences, use line breaks (\\n\\n) to separate distinct thought groups or segments.\n\n**COMBINED FORMATTING EXAMPLE:**\n\"Most people slap a prompt into some A-I tool and hope the whole page just shows up. - That never works.\\n\\nYou get blurry images, broken layouts, weird animations. - Here's what actually works.\"\n\n### ABBREVIATION PRONUNCIATION (CRITICAL)\n\n**ALL abbreviations must be hyphenated for proper pronunciation.** The avatar reads each letter separately when hyphenated.\n\n| Original | Hyphenated Version | How Avatar Says It |\n|----------|-------------------|-------------------|\n| AI | A-I | \"A I\" (two letters) |\n| CRM | C-R-M | \"C R M\" (three letters) |\n| API | A-P-I | \"A P I\" (three letters) |\n| ROI | R-O-I | \"R O I\" (three letters) |\n| SaaS | S-A-A-S | \"S A A S\" (four letters) |\n| ERP | E-R-P | \"E R P\" (three letters) |\n| SEO | S-E-O | \"S E O\" (three letters) |\n| CEO | C-E-O | \"C E O\" (three letters) |\n| PDF | P-D-F | \"P D F\" (three letters) |\n| URL | U-R-L | \"U R L\" (three letters) |\n| SQL | S-Q-L | \"S Q L\" (three letters) |\n| AWS | A-W-S | \"A W S\" (three letters) |\n| GPT | G-P-T | \"G P T\" (three letters) |\n| LLM | L-L-M | \"L L M\" (three letters) |\n| B2B | B-two-B | \"B two B\" |\n| B2C | B-two-C | \"B two C\" |\n| KPI | K-P-I | \"K P I\" (three letters) |\n| MVP | M-V-P | \"M V P\" (three letters) |\n| SOP | S-O-P | \"S O P\" (three letters) |\n| CMS | C-M-S | \"C M S\" (three letters) |\n\n**EXCEPTION - Tool names stay as-is:**\n- ChatGPT (avatar knows this)\n- GPT-4 (avatar knows this)\n- n8n (say \"n-eight-n\")\n- Claude (regular word)\n\n### LINE BREAKS FOR SEGMENT SEPARATION\n\nUse line breaks (\\n\\n) to separate distinct thought groups within a segment, IN ADDITION to \" - \" between sentences.\n\n### NATURAL PAUSES VIA PUNCTUATION\n\n**Use this hierarchy of pauses:**\n\n| Pause Type | Symbol | Length | Use For |\n|------------|--------|--------|---------|\n| Micro pause | Comma (,) | Short | Between related ideas, list items |\n| Medium pause | Period + \" - \" | Medium | Between sentences (ALWAYS) |\n| Major pause | Period + \\n\\n | Long | Between distinct ideas/segments |\n\n**Combined Example:**\n\"Here's the thing most people miss. - You can't just throw a prompt at an A-I tool, and expect magic. - It doesn't work that way.\"\n\n### DO USE\n- Contractions: don't, can't, it's, that's, here's, you're, I've, won't\n- Hyphenated abbreviations: A-I, C-R-M, A-P-I, R-O-I, S-E-O\n- \" - \" between EVERY sentence\n- Natural filler phrases: \"basically\", \"literally\", \"honestly\", \"the thing is\"\n- Line breaks between thought groups\n\n### AVOID\n- Un-hyphenated abbreviations (AI, CRM, API - these will be mispronounced)\n- Special characters: \u2014 \u2013 / & ; ...\n- Parentheses: ( )\n- Sentences without \" - \" pause markers between them\n- Long blocks of text without natural pause points\n\n### NUMBERS\n- Write as words for better pronunciation: \"five tools\" not \"5 tools\"\n- Prices as words: \"fifty bucks a month\" not \"$50/month\"\n- Years as spoken: \"twenty twenty four\" not \"2024\"\n- But keep tool names exact: \"G-P-T-4\" \"n-eight-n\" \"Claude\"\n\n### PRONUNCIATION HELPERS\n- For unclear words, use hyphens: \"a-sync\" for async\n- Spell out as spoken: \"dot com\" not \".com\"\n- ALL abbreviations get hyphenated (see table above)\n- Technical terms: explain or avoid\n\n---\n\n## YOUR TASK\n\nCreate 3 standalone short-form video concepts from the source material provided.\n\nEach concept must:\n1. Hook viewers in the first 3 seconds\n2. Deliver real value in 45-55 seconds\n3. Feel like advice from a knowledgeable friend, not a lecture\n4. End with the same global CTA (defined once, used in all 3)\n5. Be understandable by anyone, regardless of technical background\n6. Include \" - \" between EVERY sentence for natural A-I avatar pacing\n7. Use hyphenated abbreviations (A-I, C-R-M, A-P-I, etc.)\n8. **Have segments that are 4 seconds or less each** (see Segment Duration Rules)\n\n---\n\n## CONCEPT TYPES (Use each type once)\n\n### TYPE 1: PAIN\nOpens with a problem that makes viewers think \"that's me.\"\n\n**Hook style:** Call out a specific mistake, waste, or frustration\n**Body:** Agitate the problem, show the cost, reveal the fix\n**Tone:** Urgent but helpful, not preachy\n\n**Example hook patterns:**\n- \"Stop doing X. - It's costing you Y.\"\n- \"If you're still manually doing X, you're wasting hours every week.\"\n- \"Most people get this completely wrong.\"\n\n### TYPE 2: CURIOSITY\nOpens with an insight that creates a knowledge gap.\n\n**Hook style:** Share something surprising, counterintuitive, or \"secret\"\n**Body:** Build anticipation, explain context, deliver the insight\n**Tone:** Excited, like sharing a discovery\n\n**Example hook patterns:**\n- \"While everyone's been focused on X, Y quietly released Z.\"\n- \"Here's something most people don't know about X.\"\n- \"I found a way to do X that nobody's talking about.\"\n\n### TYPE 3: TRANSFORMATION\nOpens with a bold result that demands explanation.\n\n**Hook style:** State a surprising outcome or capability\n**Body:** Break down how it works, make it feel achievable\n**Tone:** Confident, let results speak\n\n**Example hook patterns:**\n- \"I built a system that does X completely automatically.\"\n- \"Here's how to X in Y minutes, step by step.\"\n- \"This one change took me from X to Y.\"\n\n---\n\n## CONTENT THEMES (WHAT PERFORMS BEST)\n\nTop-of-funnel A-I content performs best when it's about NEW and ACTIONABLE things. Prioritize these themes:\n\n### TIER 1: HIGHEST PERFORMING (Use Most Often)\n\n**New Tool Releases**\n- \"Google just dropped ten free A-I tools nobody's talking about\"\n- \"OpenAI quietly released this feature yesterday\"\n- \"This new tool just made X obsolete\"\n\n**Tool Comparisons & Recommendations**\n- \"The only three A-I tools you actually need\"\n- \"I tested five A-I writing tools. - Here's the winner.\"\n- \"Stop paying for X. - This free tool does the same thing.\"\n\n**Quick Wins & Immediate Results**\n- \"Try this in ChatGPT right now\"\n- \"Copy this prompt. - It changed how I work.\"\n- \"Five minute setup. - Saves hours every week.\"\n\n### TIER 2: STRONG PERFORMERS\n\n**Strategy & Methods**\n- \"How I use A-I to do X in half the time\"\n- \"The prompt structure that actually works\"\n- \"Most people use ChatGPT wrong. - Here's the right way.\"\n\n**Money & Career Angles**\n- \"This A-I skill is worth learning right now\"\n- \"How people are making money with X tool\"\n- \"The A-I jobs nobody's talking about\"\n\n### TIER 3: USE SPARINGLY\n\n**Industry News & Updates**\n- Only when genuinely surprising or important\n- Must include \"what this means for you\" angle\n\n**Abstract Concepts**\n- Only if tied to specific, actionable takeaway\n- Never just \"A-I is changing everything\"\n\n### TOOLS TO MENTION FREQUENTLY\n\nWhen relevant, name-drop these specific tools (audiences love specifics):\n\n| Category | Tools to Mention |\n|----------|------------------|\n| Chat A-I | ChatGPT, Claude, Gemini, Perplexity |\n| Image A-I | Midjourney, DALL-E, Ideogram, Flux |\n| Video A-I | HeyGen, Synthesia, Runway, Kling |\n| Automation | n-eight-n, Make, Zapier |\n| Writing | Jasper, Copy dot A-I, Claude |\n| Coding | Cursor, GitHub Copilot, Replit |\n| Research | Perplexity, NotebookLM, Elicit |\n\n**Why specific tools matter:** Your audience is overwhelmed by options. Telling them \"use A-I\" is useless. Telling them \"use Claude for this specific thing\" is actionable.\n\n---\n\n## SEGMENT DURATION RULES (CRITICAL)\n\n**Every segment must be 4 seconds or less.** This is a hard rule with no exceptions.\n\n### WHY THIS MATTERS\n\nShort segments allow for:\n- **Precise B-roll matching**: Each segment gets B-roll that perfectly matches what's being said\n- **Better pacing**: Keeps the video punchy and engaging\n- **Easier editing**: Clear cut points for post-production\n- **Context awareness**: B-roll selection can account for the segment before and after\n\n### WORDS PER SECOND FORMULA (CRITICAL)\n\n**Use 2.5 words per second** as the standard for natural, comfortable A-I avatar speech.\n\n**DURATION CALCULATION:**\n```\nduration_seconds = word_count \u00f7 2.5 (rounded up to nearest 0.5)\n```\n\n**REFERENCE TABLE - MEMORIZE THIS:**\n\n| Word Count | Duration (seconds) | Example |\n|------------|-------------------|---------|\n| 3-4 words | 1.5 sec | \"Here's the problem.\" |\n| 5-6 words | 2-2.5 sec | \"Most people get this wrong.\" |\n| 7-8 words | 3 sec | \"You're wasting hours every single week.\" |\n| 9-10 words | 4 sec | \"I built a system that does this completely automatically.\" |\n\n**HARD LIMITS:**\n- Maximum 10 words per segment (keeps segments \u22644 seconds)\n- Minimum 3 words per segment (avoids awkward micro-cuts)\n\n### HOW TO BUILD SEGMENTS\n\n**Step 1:** Write the narration for a thought/idea\n**Step 2:** Count the words\n**Step 3:** Calculate duration using the formula (words \u00f7 2.5)\n**Step 4:** If duration > 4 seconds, split into multiple segments\n\n### EXAMPLE: Calculating Duration\n\n**Narration:** \"Stop believing every viral post about A-I replacing your job.\"\n**Word count:** 10 words\n**Calculation:** 10 \u00f7 2.5 = 4 seconds \u2713\n\n**Narration:** \"I use a tool that searches for people based on job title, company size, whatever you want.\"\n**Word count:** 16 words\n**Calculation:** 16 \u00f7 2.5 = 6.4 seconds \u2717 (TOO LONG - must split)\n\n**Split version:**\n- Segment A: \"I use a tool that searches for people.\" (8 words = 3 sec)\n- Segment B: \"Job title, company size, whatever you want.\" (7 words = 3 sec)\n\n### SEGMENT BREAKDOWN GUIDELINES\n\n| Phase | Number of Segments | Max Words Each | Duration Each | Total Phase Duration |\n|-------|-------------------|----------------|---------------|---------------------|\n| Hook | 2-4 segments | 10 words | 1.5-4 sec | 5-8 seconds |\n| Body | 8-14 segments | 10 words | 1.5-4 sec | 30-40 seconds |\n| CTA | 1-3 segments | 10 words | 1.5-4 sec | 4-7 seconds |\n\n### COMMON MISTAKES TO AVOID\n\n**WRONG:** Deciding duration first, then cramming words in\n```\n\"duration_seconds\": 3,\n\"narration\": \"Stop believing every viral post about A-I replacing your job.\"\n// 10 words in 3 seconds = 3.3 words/sec = TOO FAST\n```\n\n**RIGHT:** Count words first, then calculate duration\n```\n\"narration\": \"Stop believing every viral post about A-I replacing your job.\"\n// 10 words \u00f7 2.5 = 4 seconds\n\"duration_seconds\": 4\n```\n\n**WRONG:** Long sentences that exceed 10 words\n```\n\"I use a tool that searches for people based on job title, company size, whatever you want.\"\n// 16 words = needs to be split\n```\n\n**RIGHT:** Break into multiple segments\n```\nSegment 1: \"I use a tool that searches for people.\" (8 words = 3 sec)\nSegment 2: \"Job title, company size, whatever you want.\" (7 words = 3 sec)\n```\n\n---\n\n## STORYBOARD STRUCTURE\n\nEach concept needs **12-20 segments** organized into phases:\n\n### HOOK PHASE (5-8 seconds total)\n- 2-4 segments, each 3-10 words\n- type: \"hook\"\n- Avatar full screen, no B-roll\n- Grab attention IMMEDIATELY \u2014 no warmup, no intro\n- First segment must create curiosity or tension\n\n### BODY PHASE (30-40 seconds total)\n- 8-14 segments, each 3-10 words\n- type: \"body\"\n- Avatar narration with supporting B-roll underneath\n- Each segment = ONE idea, ONE visual\n- Build logically: problem \u2192 context \u2192 solution OR step 1 \u2192 step 2 \u2192 step 3\n- This is where most B-roll goes\n\n### CTA PHASE (4-7 seconds total)\n- 1-3 segments, each 3-10 words\n- type: \"cta\"\n- Avatar full screen, no B-roll\n- Uses the **global CTA script** (same for all 3 concepts)\n\n### SEGMENT CREATION PROCESS\n\nFor each segment:\n1. **Write** the narration (one clear thought)\n2. **Count** the words (must be 3-10)\n3. **Calculate** duration: words \u00f7 2.5, round up to nearest 0.5\n4. **Verify** duration \u2264 4 seconds\n5. **If too long**, split into two segments\n\n---\n\n## B-ROLL TYPES AND SPECIFICATIONS\n\nEvery body segment needs B-roll. There are three types:\n\n### TYPE 1: SOURCE B-ROLL (from provided video/content)\n\nUse when you have reference footage to pull from.\n\n**Required fields:**\n- `broll_type`: \"source\"\n- `broll_index`: Which source video (0, 1, 2, etc.)\n- `broll_start_seconds`: Start timestamp in source\n- `broll_end_seconds`: End timestamp in source\n- `broll_visual_description`: What this clip shows\n- `broll_ai_prompt`: \"\" (empty string - not used for source B-roll)\n\n**Example:**\n```json\n{\n  \"broll_type\": \"source\",\n  \"broll_index\": 0,\n  \"broll_start_seconds\": 45,\n  \"broll_end_seconds\": 48,\n  \"broll_visual_description\": \"Screen recording showing n-eight-n workflow with multiple connected nodes\",\n  \"broll_ai_prompt\": \"\"\n}\n```\n\n### TYPE 2: AI-GENERATED B-ROLL\n\nUse when no source footage exists or for visual punch moments.\n\n**Required fields:**\n- `broll_type`: \"ai_generated\"\n- `broll_ai_prompt`: Full generation prompt for the A-I video tool\n- `broll_visual_description`: What this clip should show (plain language)\n- `broll_index`: -1 (placeholder - not used for A-I generated)\n- `broll_start_seconds`: -1 (placeholder - not used for A-I generated)\n- `broll_end_seconds`: -1 (placeholder - not used for A-I generated)\n\n**Example:**\n```json\n{\n  \"broll_type\": \"ai_generated\",\n  \"broll_ai_prompt\": \"Close-up of hands typing rapidly on a laptop keyboard, soft natural lighting, shallow depth of field, modern office background blurred, cinematic 4K\",\n  \"broll_visual_description\": \"Person typing quickly on laptop\",\n  \"broll_index\": -1,\n  \"broll_start_seconds\": -1,\n  \"broll_end_seconds\": -1\n}\n```\n\n### TYPE 3: NONE (Hook and CTA segments)\n\nUse for hook and CTA segments where the avatar is full screen with no B-roll.\n\n**Required fields:**\n- `broll_type`: \"none\"\n- `broll_index`: -1\n- `broll_start_seconds`: -1\n- `broll_end_seconds`: -1\n- `broll_visual_description`: \"\"\n- `broll_ai_prompt`: \"\"\n\n**Example:**\n```json\n{\n  \"broll_type\": \"none\",\n  \"broll_index\": -1,\n  \"broll_start_seconds\": -1,\n  \"broll_end_seconds\": -1,\n  \"broll_visual_description\": \"\",\n  \"broll_ai_prompt\": \"\"\n}\n```\n\n### A-I B-ROLL PROMPT STRUCTURE\n\nWhen writing A-I generation prompts, include:\n\n1. **Subject**: What's in the frame\n2. **Camera angle**: Close-up, wide shot, overhead, etc.\n3. **Motion**: Static, slow pan, tracking, etc.\n4. **Lighting**: Natural, dramatic, soft, etc.\n5. **Style**: Cinematic, documentary, minimal, etc.\n\n**Good prompt examples:**\n\n| Narration Context | A-I B-Roll Prompt |\n|-------------------|-------------------|\n| \"Everything runs automatically\" | \"Gears turning smoothly inside a machine, macro close-up, golden lighting, seamless motion, industrial aesthetic\" |\n| \"Wasting hours every week\" | \"Sand falling through an hourglass, extreme close-up, dramatic side lighting, slow motion, dark background\" |\n| \"Building something powerful\" | \"Sparks flying from welding, close-up, orange glow, slow motion, industrial workshop setting\" |\n| \"Connecting all your tools\" | \"Abstract network visualization with glowing nodes connecting, smooth camera pull-back, blue and white colors, tech aesthetic\" |\n| \"Simple and clean\" | \"Minimalist desk with single laptop and coffee cup, overhead shot, soft natural window light, clean aesthetic\" |\n\n### B-ROLL VISUAL DESCRIPTION GUIDELINES\n\nThe `broll_visual_description` field should:\n- Be plain language (not a generation prompt)\n- Describe what viewers will see\n- Help with video editing and organization\n- Serve as backup context if A-I generation fails\n\n**Examples:**\n- \"Screen recording of spreadsheet with data populating automatically\"\n- \"Person looking frustrated at laptop with many browser tabs\"\n- \"Dashboard showing analytics graphs going up\"\n- \"Hands arranging sticky notes on a whiteboard\"\n\n---\n\n## B-ROLL SELECTION PRINCIPLES\n\n### MATCH B-ROLL TO NARRATION CONTEXT\n\nSince segments are now \u22644 seconds, you can match B-roll very precisely to what's being said.\n\n**Consider the segment before and after** when selecting B-roll to ensure visual continuity.\n\n**Example sequence:**\n\n| Segment | Narration | B-Roll Type | Visual |\n|---------|-----------|-------------|--------|\n| 4 | \"Most businesses run on twelve different tools.\" | ai_generated | \"Multiple SaaS app logos floating and scattered chaotically, 3D render, dark background\" |\n| 5 | \"None of them talk to each other.\" | ai_generated | \"Two puzzle pieces that don't fit together, close-up, frustrated visual metaphor\" |\n| 6 | \"So you end up copying and pasting between them.\" | source | Screen recording of someone copy-pasting between browser tabs |\n| 7 | \"I built one system that replaces all of it.\" | ai_generated | \"Multiple streams of light converging into single bright point, abstract, cinematic\" |\n\n### THE GOLDEN RULE (UNCHANGED)\n\nThe avatar talks about a TOPIC. The B-roll shows something RELEVANT to that topic. The avatar NEVER describes or references what's on screen.\n\n### BANNED PHRASES IN NARRATION\n- \"Watch this\"\n- \"Look at this\"\n- \"See this?\"\n- \"Right here\"\n- \"As you can see\"\n- \"Let me show you\"\n- \"Notice how\"\n- \"Here I am\"\n- \"On my screen\"\n\n---\n\n## FLASH B-ROLL\n\nFlash B-roll = 2-second A-I-generated clips that add visual punch at key moments.\n\n### RULES\n- 2 seconds each, 3 per concept\n- NO TEXT in the visual\n- Metaphorical/emotional, not literal\n- Place after high-impact statements or at transitions\n- Avoid during hook and CTA (keep avatar visible)\n\n### PROMPT STRUCTURE\nInclude: subject, camera angle, motion style, lighting\nExample: \"Rocket launching with smoke and fire, cinematic slow motion, dramatic lighting\"\n\n### EXAMPLE PAIRINGS\n\n| Narration moment | Flash B-roll |\n|------------------|--------------|\n| \"Everything speeds up\" | Sports car speeding, motion blur, cinematic |\n| \"Money slipping away\" | Coins falling through fingers, slow motion, dark background |\n| \"Total chaos\" | Papers exploding, slow motion, office setting |\n| \"Breakthrough moment\" | Light breaking through clouds, golden hour |\n| \"Building something powerful\" | Welding sparks flying, close up, orange glow |\n| \"Time running out\" | Hourglass sand falling, extreme close up |\n| \"Scaling fast\" | Rocket launch, slow motion, dramatic |\n| \"Precision and control\" | Watch gears moving, macro shot, golden tones |\n\n---\n\n## GLOBAL CTA (Same for All 3 Concepts)\n\n**IMPORTANT:** All 3 video concepts use the **same CTA** and offer the **same deliverable**. This creates consistency and simplifies fulfillment.\n\n### CTA Types (Choose One for All 3 Videos)\n\n| Type | Script Example | When to Use |\n|------|----------------|-------------|\n| `comment` | \"Comment [KEYWORD] for the full breakdown.\" | Teaching methods, showing tools, how-to content |\n| `community` | \"Link to learn more is in my bio.\" | Broader educational content |\n| `subscribe` | \"Subscribe if you want more A-I tips like this.\" | News or trend-focused content |\n\n### Keyword Rules (For Comment CTAs)\n\nKeywords must be **human-readable, common English words.** This ensures viewers can easily type them.\n\n\u2705 **DO use:**\n- Single, common English words\n- Words directly related to the content\n- Words easy to spell and type\n\n\u274c **DO NOT use:**\n- Abbreviations (A-P-I, C-R-M, R-O-I)\n- Technical jargon (WEBHOOK, ENDPOINT)\n- Made-up words or combinations (SENDMENOW, GETIT)\n- Acronyms of any kind\n- Words with unusual spelling\n\n**Good keyword examples:**\n\n| Content Topic | Good Keyword |\n|---------------|--------------|\n| Lead generation automation | LEADS |\n| Email automation workflow | EMAIL |\n| Client acquisition system | CLIENTS |\n| Pricing strategies | PRICING |\n| Proposal templates | TEMPLATE |\n| Workflow automation | SYSTEM |\n| Sales process | SALES |\n| Time-saving tips | TIME |\n| Business growth | GROWTH |\n| Automation setup | BUILD |\n\n### Deliverable Prompt\n\nWrite a detailed prompt that **another agent can use to generate the actual deliverable**. Include:\n\n1. **What it is** (template, guide, prompt pack, etc.)\n2. **What it should contain** (specific items/sections)\n3. **Format** (PDF, Notion doc, Google Sheet, etc.)\n4. **Target audience** (beginners, intermediate, etc.)\n5. **Key value** (what problem it solves)\n\n**Example deliverable_prompt:**\n\n```\nCreate a PDF guide called \"Automated Lead Gen System Setup\" for beginners who want to build their first lead generation automation. Include: (1) Tool recommendations with free tier links - Apollo, Hunter, or similar, (2) Step-by-step setup instructions with screenshot placeholders, (3) Three email templates for cold outreach, (4) A Google Sheets template structure for organizing leads, (5) Troubleshooting FAQ for common issues. Keep language simple, assume no technical background. Should be 5-7 pages max.\n```\n\n### What TOFU Audiences Want in Deliverables\n\n**DO offer:**\n- Links to free tools or free tiers\n- Copy-paste prompts they can try immediately\n- Simple one-page guides (not twenty page PDFs)\n- \"Best tools for X\" lists\n- Free templates\n\n**DON'T offer:**\n- Complex technical documentation\n- Anything requiring coding knowledge\n- Overwhelming resource dumps\n- Things that require setup before seeing value\n\n---\n\n## TIMING TARGETS\n\n### THE GOLDEN RULE: 2.5 WORDS PER SECOND\n\nAlways calculate duration from word count, never the reverse.\n\n```\nduration_seconds = word_count \u00f7 2.5\n```\n\n### SEGMENT LIMITS\n- **Maximum words per segment**: 10 (keeps duration \u22644 seconds)\n- **Minimum words per segment**: 3 (avoids awkward micro-cuts)\n- **Words per second**: 2.5 (natural speaking pace)\n\n### PHASE TARGETS\n- **Hook phase**: 5-8 seconds total (2-4 segments)\n- **Body phase**: 30-40 seconds total (8-14 segments)\n- **CTA phase**: 4-7 seconds total (1-3 segments)\n\n### VIDEO TOTALS\n- **Total duration**: 45-55 seconds\n- **Total word count**: 110-140 words\n- **Total segments**: 12-20 segments\n\n### QUICK REFERENCE\n\n| Words | Seconds |\n|-------|---------|\n| 4 | 1.5 |\n| 5 | 2 |\n| 6 | 2.5 |\n| 7 | 3 |\n| 8 | 3 |\n| 9 | 3.5 |\n| 10 | 4 |\n\nShorter is better. If you can say it in fewer words, do it.\n\n---\n\n## QUALITY CHECKLIST\n\nBefore outputting, verify each concept:\n\n### Script Quality\n- [ ] Hook grabs attention in first 3 seconds (no warmup)\n- [ ] Uses contractions naturally (don't, it's, here's)\n- [ ] Sentences are short and punchy\n- [ ] Would sound natural if spoken to a friend\n- [ ] No banned phrases referencing B-roll\n- [ ] Total runtime 45-55 seconds\n\n### Segment Duration & Word Count (CRITICAL)\n- [ ] EVERY segment has 10 words or fewer\n- [ ] EVERY segment has 3 words or more\n- [ ] Duration calculated as: word_count \u00f7 2.5 (rounded up to nearest 0.5)\n- [ ] No segment exceeds 4 seconds\n- [ ] Hook phase has 2-4 segments totaling 5-8 seconds\n- [ ] Body phase has 8-14 segments totaling 30-40 seconds\n- [ ] CTA phase has 1-3 segments totaling 4-7 seconds\n- [ ] Total segment count is 12-20\n- [ ] Total word count is 110-140 words\n\n### Accessibility\n- [ ] No unexplained technical jargon\n- [ ] Outcomes explained, not just mechanisms\n- [ ] Would pass the \"grandmother test\"\n- [ ] Complex concepts have simple analogies\n\n### Speech & Pauses (CRITICAL FOR HEYGEN)\n- [ ] \" - \" between sentences when multiple sentences in one segment\n- [ ] ALL abbreviations hyphenated (A-I, C-R-M, A-P-I, etc.)\n- [ ] Line breaks (\\n\\n) between major thought groups\n- [ ] Strategic commas for micro-pauses within sentences\n- [ ] Numbers written as words\n- [ ] No long blocks of text without pause markers\n\n### Abbreviation Check\n- [ ] AI \u2192 A-I\n- [ ] CRM \u2192 C-R-M\n- [ ] API \u2192 A-P-I\n- [ ] ROI \u2192 R-O-I\n- [ ] SaaS \u2192 S-A-A-S\n- [ ] Any other abbreviations \u2192 hyphenated\n\n### B-Roll Quality\n- [ ] Every segment has `broll_type` specified (\"source\", \"ai_generated\", or \"none\")\n- [ ] Hook and CTA segments use `broll_type`: \"none\"\n- [ ] Body segments use either \"source\" or \"ai_generated\"\n- [ ] Source B-roll has: valid broll_index (0+), valid timestamps (0+), visual_description, empty broll_ai_prompt (\"\")\n- [ ] A-I B-roll has: broll_ai_prompt filled, visual_description filled, -1 for index/timestamps\n- [ ] \"none\" B-roll has: -1 for all numeric fields, \"\" for all string fields\n- [ ] **NO null values anywhere in the output**\n\n### Global CTA Quality\n- [ ] CTA type chosen (comment, community, or subscribe)\n- [ ] If comment CTA: keyword is a simple English word (NOT an abbreviation)\n- [ ] CTA script is 3-10 words\n- [ ] Deliverable prompt is detailed enough for another agent to create it\n- [ ] Same CTA used in all 3 concepts\n\n---\n\n## OUTPUT FORMAT\n\nReturn your response as valid JSON matching the provided schema.\n\n**CRITICAL REQUIREMENTS:**\n- Count words in each segment FIRST, then calculate duration (words \u00f7 2.5)\n- Every segment must have 3-10 words (no exceptions)\n- Include `word_count` for every segment\n- Include `broll_type` for every segment (\"source\", \"ai_generated\", or \"none\")\n- **NEVER use null values** - use placeholder values instead:\n  - For unused numeric fields: use -1\n  - For unused string fields: use \"\" (empty string)\n- Include \" - \" between sentences when segments have multiple sentences\n- Hyphenate ALL abbreviations (A-I, C-R-M, A-P-I, R-O-I, S-A-A-S, etc.)\n- **Use the same global CTA for all 3 concepts**\n\n**PLACEHOLDER VALUE RULES:**\n\n| Field | When Not Used | Placeholder Value |\n|-------|---------------|-------------------|\n| `broll_index` | A-I generated or no B-roll | -1 |\n| `broll_start_seconds` | A-I generated or no B-roll | -1 |\n| `broll_end_seconds` | A-I generated or no B-roll | -1 |\n| `broll_ai_prompt` | Source B-roll or no B-roll | \"\" |\n| `broll_visual_description` | No B-roll (hook/CTA) | \"\" |\n\n**Segment formatting examples:**\n\n**Source B-roll segment:**\n```json\n{\n  \"segment_number\": 4,\n  \"type\": \"body\",\n  \"narration\": \"It dumps everything into a spreadsheet automatically.\",\n  \"word_count\": 7,\n  \"duration_seconds\": 3,\n  \"visual_description\": \"Avatar speaking with B-roll overlay\",\n  \"broll_type\": \"source\",\n  \"broll_index\": 0,\n  \"broll_start_seconds\": 45,\n  \"broll_end_seconds\": 48,\n  \"broll_visual_description\": \"Google Sheets with data rows appearing automatically\",\n  \"broll_ai_prompt\": \"\"\n}\n```\n\n**A-I generated B-roll segment:**\n```json\n{\n  \"segment_number\": 6,\n  \"type\": \"body\",\n  \"narration\": \"Then another system picks up each lead.\",\n  \"word_count\": 7,\n  \"duration_seconds\": 3,\n  \"visual_description\": \"Avatar speaking with B-roll overlay\",\n  \"broll_type\": \"ai_generated\",\n  \"broll_index\": -1,\n  \"broll_start_seconds\": -1,\n  \"broll_end_seconds\": -1,\n  \"broll_visual_description\": \"Automation grabbing data point\",\n  \"broll_ai_prompt\": \"Robotic arm picking up glowing data orb, factory setting, blue neon lighting, smooth motion, tech aesthetic\"\n}\n```\n\n**Hook segment (no B-roll):**\n```json\n{\n  \"segment_number\": 1,\n  \"type\": \"hook\",\n  \"narration\": \"Here's how to build a lead system that runs itself.\",\n  \"word_count\": 10,\n  \"duration_seconds\": 4,\n  \"visual_description\": \"Avatar speaking full screen\",\n  \"broll_type\": \"none\",\n  \"broll_index\": -1,\n  \"broll_start_seconds\": -1,\n  \"broll_end_seconds\": -1,\n  \"broll_visual_description\": \"\",\n  \"broll_ai_prompt\": \"\"\n}\n```\n\n**CTA segment (no B-roll):**\n```json\n{\n  \"segment_number\": 13,\n  \"type\": \"cta\",\n  \"narration\": \"Comment LEADS for the full breakdown.\",\n  \"word_count\": 6,\n  \"duration_seconds\": 2.5,\n  \"visual_description\": \"Avatar speaking full screen\",\n  \"broll_type\": \"none\",\n  \"broll_index\": -1,\n  \"broll_start_seconds\": -1,\n  \"broll_end_seconds\": -1,\n  \"broll_visual_description\": \"\",\n  \"broll_ai_prompt\": \"\"\n}\n```\n\n**Word count validation example:**\n```\nNarration: \"It dumps everything into a spreadsheet automatically.\"\nWords: It(1) dumps(2) everything(3) into(4) a(5) spreadsheet(6) automatically(7) = 7 words\nDuration: 7 \u00f7 2.5 = 2.8 \u2192 round up to 3 seconds\n```\n\nFor full_script, combine all narration with `\\n\\n` between segments:\n```json\n\"full_script\": \"Here's how to build a lead system that runs itself.\\n\\nStep by step, no code required.\\n\\nFirst, you need something that finds customers.\\n\\nI use a tool that searches by job title.\\n\\nCompany size, location, whatever you want.\\n\\nIt dumps everything into a spreadsheet automatically.\\n\\nThen another system picks up each lead.\\n\\nIt researches their company automatically.\\n\\nThen writes a personalized email. - Not templates.\\n\\nIt sends from your real inbox.\\n\\nAnd tracks who opens it.\\n\\nThe whole thing runs while you sleep.\\n\\nComment LEADS for the full breakdown.\"\n```\n\n---\n\n## EXAMPLE OUTPUT STRUCTURE\n\nHere's the TONE, STYLE, SEGMENT STRUCTURE, WORD COUNT CALCULATIONS, and B-ROLL HANDLING to aim for:\n\n**HOOK PHASE (2 segments):**\n\nSegment 1 (type: hook):\nNarration: \"Here's how to build a lead system that runs itself.\"\nWord count: 10 words \u2192 10 \u00f7 2.5 = **4 sec**\nB-roll: none\n\nSegment 2 (type: hook):\nNarration: \"Step by step, no code required.\"\nWord count: 6 words \u2192 6 \u00f7 2.5 = **2.5 sec**\nB-roll: none\n\n**BODY PHASE (10 segments):**\n\nSegment 3 (type: body):\nNarration: \"First, you need something that finds customers.\"\nWord count: 7 words \u2192 7 \u00f7 2.5 = **3 sec**\nB-roll: ai_generated - \"Search results appearing on screen, digital data visualization, blue glow, tech aesthetic\"\n\nSegment 4 (type: body):\nNarration: \"I use a tool that searches by job title.\"\nWord count: 9 words \u2192 9 \u00f7 2.5 = **3.5 sec**\nB-roll: source - Screen recording of LinkedIn Sales Navigator search filters\n\n...continue pattern...\n\nSegment 12 (type: body):\nNarration: \"The whole thing runs while you sleep.\"\nWord count: 7 words \u2192 7 \u00f7 2.5 = **3 sec**\nB-roll: ai_generated - \"Clock hands spinning fast, city day-to-night timelapse in background, cinematic\"\n\n**CTA PHASE (1 segment):**\n\nSegment 13 (type: cta):\nNarration: \"Comment LEADS for the full breakdown.\"\nWord count: 6 words \u2192 6 \u00f7 2.5 = **2.5 sec**\nB-roll: none\n\n**TOTALS:**\n- Word count: ~95 words\n- Duration: ~38 seconds (+ flash B-roll = ~44 seconds)\n- Segments: 13\n\n**GLOBAL CTA (applies to all 3 concepts):**\n- **CTA Type:** comment\n- **Keyword:** LEADS\n- **CTA Script:** \"Comment LEADS for the full breakdown.\"\n- **Deliverable Prompt:** \"Create a PDF guide called 'Automated Lead Gen System' for beginners. Include: (1) Tool recommendations with free tiers - Apollo, Hunter, Instantly, (2) Step-by-step setup with screenshot placeholders, (3) Three cold email templates, (4) Google Sheets template for lead tracking, (5) Common mistakes FAQ. Keep it simple, 5-7 pages max, assume zero technical background.\"\n\n**FLASH B-ROLL (3 clips per concept):**\n1. After segment 6: \"Coins stacking automatically, stop motion style, clean white background, satisfying visual\"\n2. After segment 9: \"Light bulb illuminating, close-up filament, warm orange glow, shallow depth of field\"\n3. After segment 12: \"Rocket launching, slow motion, dramatic lighting, smoke and fire detail\"\n\n---\n\n## FINAL REMINDER: NO NULL VALUES\n\n**CRITICAL:** The output must NEVER contain null values. Always use the appropriate placeholder:\n\n| Situation | Field | Use This |\n|-----------|-------|----------|\n| No B-roll needed | broll_index | -1 |\n| No B-roll needed | broll_start_seconds | -1 |\n| No B-roll needed | broll_end_seconds | -1 |\n| No B-roll needed | broll_visual_description | \"\" |\n| No B-roll needed | broll_ai_prompt | \"\" |\n| Source B-roll (no AI prompt needed) | broll_ai_prompt | \"\" |\n| AI-generated B-roll (no source needed) | broll_index | -1 |\n| AI-generated B-roll (no source needed) | broll_start_seconds | -1 |\n| AI-generated B-roll (no source needed) | broll_end_seconds | -1 |\n| Non-comment CTA | keyword | \"\" |\n\nThis ensures the JSON output is always valid and can be processed by downstream automation systems without errors."
            },
            {
              "id": "aabe9b89-7ce9-4222-8b74-cd30799e1914",
              "name": "Examples",
              "type": "string",
              "value": "=[\n  {\n    \"creator_handle\": \"nick_saraev\",\n    \"creator_name\": \"Nick Saraev\",\n    \"transcript\": \"Stop building your AI agents from scratch. Somebody just leaked 2,000 ready-to-use N8N templates on this secret repo. These cover everything: social media automation, email sequences, CRM updates, lead gen, all of it. Just download the template and upload to your own self-hosted N8N. I'm using Hostinger because they got N8N built in and they deploy in just a minute, plus they give you an additional free 100 templates that you could use. You guys want the full repo plus 10% off hosting? Just comment automation and I'll send you everything directly.\",\n    \"caption\": \"Comment \\\"AUTOMATION\\\" to get this Free Github Repo packed with 2000+ n8n Automations and AI Agents.\\n\\nStop wasting time building AI agents from scratch. Seriously.\\n\\nSomeone just leaked 2,000+ ready-to-use n8n templates on a secret GitHub repo. These aren't random bits thrown together. They're well-organized workflows covering everything you can think of:\\n\\n 1. Social media automation\\n 2. Email sequences\\n 3. CRM updates\\n 4. Lead generation\\n 5. Data syncing\\n\\nIf you want to automate it, the template is probably already there.\\n\\nHere's the best part. Instead of spending days building, just grab what you need, download the template, and upload it to your n8n setup. It's that simple.\\n\\nI tried this myself recently. I was blown away by how fast I got things running. No complicated coding. No headaches.\\n\\nIf you're wondering where to host your n8n, I recommend Hostinger. Why? They have n8n built in. You deploy in under a minute. Plus, they throw in 100+ more free templates. It's like having a starter kit ready to go.\\n\\nImagine it like cooking with a pre-made sauce instead of starting from scratch. It tastes great, saves time, and you can still tweak it to your taste.\\n\\nSo, before you dive into building an AI workflow from zero, check out this repo. Download. Upload. Automate fast.\\n\\n#n8n #aiautomation #hostinger #aiagents #aitools #ainews #aiindia #aicommunity #selfhostn8n\",\n    \"likes\": 3971,\n    \"shares\": 2300,\n    \"comments\": 5399,\n    \"plays\": 136970,\n    \"views\": 31448,\n    \"duration_seconds\": 27.469,\n    \"posted_at\": \"2025-12-11T14:51:46.000Z\",\n    \"url\": \"https://www.instagram.com/p/DSII1C3Ek3s/\",\n    \"engagement_rate\": 37.11,\n    \"hook\": \"Stop building your AI agents from scratch.\"\n  },\n  {\n    \"creator_handle\": \"nateherkai\",\n    \"creator_name\": \"Nate Herk\",\n    \"transcript\": \"You're learning NNN wrong. If you're jumping straight into AI agents, then you're doing it backwards. You can't build good agents until you understand workflows. If I was starting from zero in 2026, this is the exact order I'd follow. First, workflows. No AI, no agents. Learn how data comes in, how it moves, how it leaves, triggers, variables, conditions, errors. This stuff is boring, but you'll get good very fast if you learn it. Then, I'd move into AI-assisted workflows. Same structure, but now AI makes small, controlled decisions inside the system. Only after all that would I touch full AI agents. Because agents are powerful, but they break constantly if your foundations suck. So once workflows and data finally click, NNN stops feeling confusing. You stop guessing, you stop messing things up, and everything starts to make sense. But I know it's easier said than done, so I broke this entire learning roadmap down step by step in a full YouTube video. Just comment video, and I'll go ahead and send it over.\",\n    \"caption\": \"Comment 'VIDEO' and I'll send it you.\",\n    \"likes\": 3166,\n    \"shares\": 1520,\n    \"comments\": 4412,\n    \"plays\": 70890,\n    \"views\": 24746,\n    \"duration_seconds\": 43.669,\n    \"posted_at\": \"2026-01-04T12:03:33.000Z\",\n    \"url\": \"https://www.instagram.com/p/DTFomVBFKrX/\",\n    \"engagement_rate\": 36.77,\n    \"hook\": \"You're learning NNN wrong.\"\n  },\n  {\n    \"creator_handle\": \"nateherkai\",\n    \"creator_name\": \"Nate Herk\",\n    \"transcript\": \"Christmas just came early for anyone trying to learn AI and NNN, because I'm giving away something I should honestly be charging for. I built a full eight-hour masterclass that takes a complete beginner and turns them into someone who can actually build real AI automations. Fifteen practical examples, real workflows, agents that actually work. And all explained like you've never touched NNN before. So if you want the full eight-hour course for free, just comment masterclass and I'll send it down your chimney or to your DMs.\",\n    \"caption\": \"Comment 'MASTERCLASS' and I'll send it you\",\n    \"likes\": 19289,\n    \"shares\": 12394,\n    \"comments\": 71988,\n    \"plays\": 678663,\n    \"views\": 287817,\n    \"duration_seconds\": 22.677,\n    \"posted_at\": \"2025-12-19T21:03:53.000Z\",\n    \"url\": \"https://www.instagram.com/p/DSdZtG7k80v/\",\n    \"engagement_rate\": 36.02,\n    \"hook\": \"Christmas just came early for anyone trying to learn AI and NNN, because I'm giving\"\n  },\n  {\n    \"creator_handle\": \"nick_saraev\",\n    \"creator_name\": \"Nick Saraev\",\n    \"transcript\": \"You don't need to build AI automations from scratch anymore, because I'm about to share three websites where you guys can find over 3,000 n8n automation templates that you can easily download and then plug into your workflows with just a few clicks. First, there's this GitHub repo, which has over 200 real-world ready-to-use templates for automating your social media, emails, research, CRMs, and much more. Then, there's the official n8n website. You can search and download over 2,000 more automations here, covering everything from beginner to super advanced. And finally, these 30 high-ROI automation templates that you guys can sell to any business for $3,000 a pop or more. I've created these myself, and each of them comes with a detailed video guide to help you set them up step-by-step. So, if you guys want all of my templates, just comment \\\"automation\\\" down below, and I'll shoot them over to you via DM.\",\n    \"caption\": \"Comment \\\"AUTOMATION\\\" to get these 3000+ Free n8n Automation templates.\\n\\nYou don't need to build AI automations from scratch anymore.\\n\\nBecause here's the thing, there are already thousands of ready-to-use n8n templates online. Real workflows. Real results. And all you need are a few clicks to make them your own.\\n\\nLet me show you where to find them.\\n\\nFirst, there's a GitHub repo that hosts over 200 automation templates. These aren't just random experiments. They're built for real business tasks\u2014like managing emails,\\n\\nscheduling social posts, updating CRMs, and handling research. Each template connects popular tools like Gmail, Slack, Google Drive, and Telegram. Think of it as your personal toolbox for work automation.\\n\\nNext stop: the official n8n website. You'll find over 2,000 more templates there. Some are beginner-friendly. Others are advanced. You can filter by category, preview the setup, and download them instantly. It's like browsing a library of ready-to-run workflows\u2014built by the community, tested by users, and easy to customize.\\n\\nAnd then\u2026 there's my collection. Fifty high-ROI automations I built myself. These ones are special. Why? Because businesses actually pay for them. I've sold some for four-figures and more\u2014and they keep selling. Each one comes with a step-by-step video walkthrough, showing exactly how to install and use it.\\n\\nThe best part? You don't need to be a tech wizard. You just need curiosity, a laptop, and five minutes to plug these templates into your workflow.\\n\\nBuild smarter. Not from scratch.\\n\\n#n8naiagents #n8n #n8nautomations #aiautomations #aitools #ainews #aiindia #aicommunity #githubrepo\",\n    \"likes\": 3237,\n    \"shares\": 1972,\n    \"comments\": 5101,\n    \"plays\": 109590,\n    \"views\": 28680,\n    \"duration_seconds\": 42.168,\n    \"posted_at\": \"2025-11-07T18:08:32.000Z\",\n    \"url\": \"https://www.instagram.com/p/DQw8W0vgUby/\",\n    \"engagement_rate\": 35.95,\n    \"hook\": \"You don't need to build AI automations from scratch anymore, because I'm about to share\"\n  },\n  {\n    \"creator_handle\": \"nateherkai\",\n    \"creator_name\": \"Nate Herk\",\n    \"transcript\": \"I built a system that auto-posts content across nine different social accounts. No logging into platforms, no copy-pasting, no forgetting to post. Here's how it works. So all your content lives in one place: title, caption, media, and a simple status like \\\"ready to post.\\\" When the workflow runs, it pulls one post that's marked ready, and it uploads the media. Then it publishes that same post across all of the different social platforms. Once it's done, it marks the post as posted in your database so it never duplicates content. If anything fails, it flags it so you know exactly what needs fixing, and you don't need to manage nine platforms anymore. You just need to manage one system. So I made a full video breaking down this exact system, and I'll give you the template for free. Just comment \\\"social\\\" and I'll send it over.\",\n    \"caption\": \"Comment 'SOCIAL' and I'll send it you.\",\n    \"likes\": 682,\n    \"shares\": 278,\n    \"comments\": 801,\n    \"plays\": 17976,\n    \"views\": 5043,\n    \"duration_seconds\": 33.237,\n    \"posted_at\": \"2026-01-06T17:03:07.000Z\",\n    \"url\": \"https://www.instagram.com/p/DTLUlwflax7/\",\n    \"engagement_rate\": 34.92,\n    \"hook\": \"I built a system that auto-posts content across nine different social accounts.\"\n  },\n  {\n    \"creator_handle\": \"nick_saraev\",\n    \"creator_name\": \"Nick Saraev\",\n    \"transcript\": \"You don't need to pay for Bolt, VZero, or any other AI coder anymore. Just use this new AI tool that lets you build fully functioning apps and websites without writing a single line of code. Unlike other AI coders, it doesn't just build the front end and the back end, it also handles your database, user login, and payments integrations all on its own. You just describe your app idea in plain English and the AI then starts building it for you. So if you want to try it for yourself, just comment coding down below and I'll send you guys the link directly.\",\n    \"caption\": \"Comment \\\"CODING\\\" to get this new AI Coder that can build full-stack apps in just 30 minutes.\\n\\nTired of paying for AI coders like Lovable, Bolt or V0? You don't need those AI coders anymore.\\n\\nUse Anything AI instead. It lets you build full apps and websites. No code needed.\\n\\nOther tools? They just make the front end. Or the back end. Anything AI does more.\\n\\nIt handles your database. User login. Payments too. All on its own.\\n\\nPicture this. Like telling a smart friend your idea. They build it for you.\\n\\nI tried it last week. Said, \\\"Make a simple task app with user sign-up and Stripe pay.\\\" Boom. It worked in minutes.\\n\\nJust describe your app in plain English. The AI starts building. Right away.\\n\\nWhy does this beat others? Here's how:\\n\\n1. Full front and back end. Done.\\n2. Database set up. No hassle.\\n3. Logins secure. Users happy.\\n4. Payments easy. Money flows.\\n\\nShort steps. First, type your idea. Like, \\\"Fitness tracker with profiles.\\\" Preview pops up. Tweak it. \\\"Add workouts.\\\" Done.\\n\\nThe good news? You get live previews. Fast.\\n\\nEven pros save time. I built a side project. Took hours, not days.\\n\\nExport code if you want. React. Node. Whatever.\\n\\nFree to start. Plans are cheap. Perfect for quick MVPs. Or testing ideas.\\n\\n#anythingai #aicoding #vibecoding #boltai #cursorai\",\n    \"likes\": 1721,\n    \"shares\": 858,\n    \"comments\": 5092,\n    \"plays\": 86390,\n    \"views\": 22409,\n    \"duration_seconds\": 23.312,\n    \"posted_at\": \"2026-01-11T16:08:56.000Z\",\n    \"url\": \"https://www.instagram.com/p/DTYGPyOD2Wy/\",\n    \"engagement_rate\": 34.23,\n    \"hook\": \"You don't need to pay for Bolt, VZero, or any other AI coder anymore.\"\n  },\n  {\n    \"creator_handle\": \"nick_saraev\",\n    \"creator_name\": \"Nick Saraev\",\n    \"transcript\": \"Okay, stop building your in8n animations from scratch. Instead, use this AI tool that lets you create entire automations just by chatting with it. You just describe the automation you want, and the AI will build it for you in seconds, all on its own. Or, you can simply paste a screenshot of any workflow, and it'll do its best to recreate it in under a minute. Plus, you can also use it to edit or debug existing workflows, too. Want to try it? Just comment Automation down below, and I'll send you all the link directly.\",\n    \"caption\": \"Comment \\\"AUTOMATION\\\" to get this AI Extension that can build full n8n Automations for you by just chatting.\\n\\nTired of building n8n automations from scratch, stop immediately.\\n\\nI also used to spend hours dragging nodes around. Wiring triggers. Fixing errors. Not anymore.\\n\\nMeet n8nChat. It's a Chrome extension. You chat with it. And it builds your whole workflow.\\n\\nJust tell it what you want. Like this: \\\"Grab leads from Google Sheets. Score them with AI. Ping Slack for the hot ones.\\\" Seconds later. Done. Ready to run.\\n\\nOr take a screenshot of any workflow. Paste it in. It copies it perfectly. In one minute flat. No more guessing.\\n\\nNeed to fix a bug? Chat again. \\\"Make this email node stop crashing.\\\" It edits right there.\\nThe good news? It works on your stuff too.\\n\\nI tried it last week. Had a messy Airtable sync. Told it the problem. Fixed in 20 seconds. Like magic. Easier than tying your shoes.\\n\\nWhy drag and drop? When you can just talk.\\n\\nHere's what it does for you:\\n\\n 1. Builds new flows from your words\\n 2. Copies screenshots to n8n\\n 3. Debugs your broken nodes\\n 4. Tweaks old workflows fast\\n\\nThink of it like this. Building by hand is like cooking from raw ingredients. n8nChat? It's your personal chef. You say the dish. It cooks.\\n\\nSelf-hosted or cloud. Works anywhere. Free to try.\\n\\nI ditched my scratch builds after one test. You should too.\\n\\nWant to give it a shot? Grab it from the Chrome store. Tell me your first idea.\\n\\n#n8n #aiautomations #n8nchat #n8naiagents #nicksaraev\",\n    \"likes\": 2568,\n    \"shares\": 1468,\n    \"comments\": 5262,\n    \"plays\": 101428,\n    \"views\": 28007,\n    \"duration_seconds\": 22.801,\n    \"posted_at\": \"2025-12-30T17:25:59.000Z\",\n    \"url\": \"https://www.instagram.com/p/DS5VThhj50V/\",\n    \"engagement_rate\": 33.2,\n    \"hook\": \"Okay, stop building your in8n animations from scratch.\"\n  },\n  {\n    \"creator_handle\": \"nateherkai\",\n    \"creator_name\": \"Nate Herk\",\n    \"transcript\": \"I built a system that generates and uploads faceless YouTube Shorts on autopilot. You load in ideas one time, and it can start to pump out Shorts every day while you sleep. So here's the flow. Everything starts with a simple sheet. Each row is one video idea plus a status like to-do. When the workflow runs, it grabs one idea that's marked as to-do, and it generates the visuals. So first, it creates clean image prompts from your idea, turns those image prompts into images, turns those images into shorter video clips, and then it generates the audio. It creates a sound prompt based on the vibe of the video and stitches it together for the final edit. After that's been rendered, it uploads it to YouTube automatically. And at the end, it updates that spreadsheet so your idea gets marked as done. It adds the final video link, it sends you a notification so that you can review it. So now you're not editing, you're not uploading, you're just feeding the system ideas. So I made a full video showing this exact workflow, and now I'm giving you the template for free. Just comment faceless, and I'll send it over.\",\n    \"caption\": \"Comment 'FACELESS' and I'll send it in DM's.\",\n    \"likes\": 616,\n    \"shares\": 220,\n    \"comments\": 787,\n    \"plays\": 16359,\n    \"views\": 4989,\n    \"duration_seconds\": 44.133,\n    \"posted_at\": \"2026-01-07T12:04:03.000Z\",\n    \"url\": \"https://www.instagram.com/p/DTNW-VTD6ix/\",\n    \"engagement_rate\": 32.53,\n    \"hook\": \"I built a system that generates and uploads faceless YouTube Shorts on autopilot.\"\n  },\n  {\n    \"creator_handle\": \"nick_saraev\",\n    \"creator_name\": \"Nick Saraev\",\n    \"transcript\": \"Someone just dropped thousands of AI agents and automations onto one GitHub repo. And these aren't just your basic workflows. They're real-world, ready-to-use templates for automating your social media, your emails, your databases, your CRMs, and much, much more. And you can easily download and plug them into your N8N with just a few clicks. So if you guys want to check them out, just comment agents down below and I'll send you the link.\",\n    \"caption\": \"Comment \\\"AGENT\\\" to get this Free Gtihub repo filled with 4000+ n8n AI Agents and Automation templates.\\n\\nSomeone just dropped thousands of AI agents and automations into one huge GitHub repo. And these aren't your usual, simple workflows.\\n\\nThey're real, ready-to-use templates for automating everything from social media and emails to databases and CRMs.\\n\\nHere's the deal: there are 4,343 production-ready workflows you can use right away. They cover 365 unique integrations \u2014 think Slack, Google Workspace, Stripe, Airtable, Notion, and many more.\\n\\nAll together, these workflows include 29,445 nodes working behind the scenes. And they're organized neatly into 15 categories.\\n\\nThe best part? Every single one imports cleanly into N8N, so you can start automating in just a few clicks.\\n\\nWhy does this matter? Well, automating your daily digital tasks\u2014like posting on social media, sending emails, or updating your CRM\u2014is usually a headache. You have to build everything from scratch or piece together disconnected tools.\\n\\nBut this repo gives you a giant toolbox with flexible, battle-tested workflows ready to plug into N8N, a popular no-code/low-code automation platform.\\n\\nIf you already use N8N, this is a time-saver. You don't have to build your own workflows or code integrations. Just download, import, and connect to your accounts. For those new to N8N, it's a visual tool that lets you create automations without coding, but with the power to go deep when needed.\\n\\nI recently tested some of these workflows, and setting them up took minutes\u2014not hours. It made automating my business tasks way simpler and faster.\\n\\nIf you want to manage complex automations without writing code, this repo is a goldmine. Just pick what fits your needs and instantly add AI-driven automation to your toolkit.\\n\\nIn short: this massive library turns automation from a chore into a few clicks of convenience.\\n\\n#n8n #n8nautomation #aiagents\",\n    \"likes\": 4211,\n    \"shares\": 2498,\n    \"comments\": 7350,\n    \"plays\": 163479,\n    \"views\": 44075,\n    \"duration_seconds\": 19.226,\n    \"posted_at\": \"2025-11-25T18:59:56.000Z\",\n    \"url\": \"https://www.instagram.com/p/DRfYhXVkrZg/\",\n    \"engagement_rate\": 31.9,\n    \"hook\": \"Someone just dropped thousands of AI agents and automations onto one GitHub repo.\"\n  },\n  {\n    \"creator_handle\": \"nick_saraev\",\n    \"creator_name\": \"Nick Saraev\",\n    \"transcript\": \"This is a $2,000 AI automation that can transform any podcast into hundreds of viral TikTok and Instagram clips all on its own. It automatically extracts the best highlights, adds subtitles, generates captions, and even posts everything for you. You can easily sell this system to podcasters, content creators, or agency owners for $1,000 to $2,000 a pop or more. It's built in NANET and has two main sections. First, it scrapes a YouTube channel for its latest uploads and sends them to Vizard AI. The AI then analyzes the whole episode and automatically turns the most engaging segments into clips. Next, the other section retrieves those generated shorts and uses ChatGPT to write captions for each post. Finally, it stores all the data in Google Sheets and notifies you when it's done. So if you guys want this automation, along with a detailed video guide on how to set it up for yourself, just comment video and I'll send it to you via DMs for free.\",\n    \"caption\": \"Comment \\\"VIDEO\\\" to get this Viral clipper n8n automation.\\n\\nYou're looking at a simple AI automation that you can sell for four to five low figures. It takes any podcast and turns it into hundreds of TikTok and Instagram clips. All on its own. No video editor. No manual chopping. No guessing what will hit.\\n\\nHere's what it does for you and your clients:\\n\\n 1. Finds the best moments from long podcast episodes\\n 2. Cuts them into short, vertical clips\\n 3. Adds subtitles automatically\\n 4. Writes captions for each post\\n 5. Stores everything neatly and lets you know when it's ready\\n\\nYou can sell this to:\\n - Podcasters who hate editing\\n - Content creators who want more short-form clips\\n - Agency owners who manage creators and need a system\\n\\nCharge 4 to 5 figures per setup. Per client. Think about it. One client can pay for your whole month. Two or three? You're doing very well.\\n\\nIt's built in n8n and has two main parts.\\n\\nFirst part: n8n checks a YouTube channel for new uploads. When a new podcast drops, it sends that video to Vizard AI. Vizard then analyzes the full episode. It looks for hooks, jokes, insights, strong opinions. The parts people actually share. Then it turns those into short clips. Perfect for TikTok and Instagram Reels.\\n\\nSecond part: n8n grabs those finished clips. For each clip, it calls ChatGPT.\\n\\nChatGPT writes a short, catchy caption for social media. Then n8n saves the clip links, captions, and other details into a Google Sheet. At the end, it pings you. So you know the clips are ready to review, schedule, or post.\\n\\nI built a similar flow once for a small creator. He went from posting one clip a week\u2026 to posting two clips a day. Same podcast. Same content. Just smarter automation.\\n\\nSo, if you want this automation, plus a clear video guide showing how to set it up step by step\u2026 you can start offering it as a done-for-you system to clients fast.\\n\\n#n8n #n8nautomation #aiautomations #vizardai #aiclipper\",\n    \"likes\": 2188,\n    \"shares\": 1126,\n    \"comments\": 3897,\n    \"plays\": 78154,\n    \"views\": 22972,\n    \"duration_seconds\": 45.326,\n    \"posted_at\": \"2026-01-06T15:58:20.000Z\",\n    \"url\": \"https://www.instagram.com/p/DTLNK-Cj_8l/\",\n    \"engagement_rate\": 31.39,\n    \"hook\": \"This is a $2,000 AI automation that can transform any podcast into hundreds of viral\"\n  }\n]"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ff5b9bd7-cc1c-4660-8762-06b37ca91f8d",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 2,
      "position": [
        7920,
        2000
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Uploaded",
            "Hashtags": "={{ $json.output[0].content[0].text.hashtags }}",
            "Concept #": "={{ $('Loop Through Concepts').item.json.concept_number }}",
            "Short Title": "={{ $('Loop Through Concepts').item.json.title }}",
            "Concept Type": "={{ $('Loop Through Concepts').item.json.concept_type }}",
            "Created Date": "={{ DateTime.fromSeconds($json.created_at).toFormat('yyyy-MM-dd HH:mm:ss') }}",
            "YouTube Title": "={{ $json.output[0].content[0].text.youtube.title }}",
            "TikTok Caption": "={{ $json.output[0].content[0].text.tiktok.caption }}",
            "YouTube Caption": "={{ $json.output[0].content[0].text.youtube.description }}",
            "Source Video URL": "={{ $('Shorts Trigger').item.json.source.youtube_url }}",
            "Google Drive Link": "={{ $('Upload to Google Drive').item.json.webViewLink }}",
            "Instagram Caption": "={{ $json.output[0].content[0].text.instagram.long_caption }}",
            "Source Video Name": "={{ $('Shorts Trigger').item.json.source.video_name }}"
          },
          "schema": [
            {
              "id": "Created Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Created Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source Video Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Source Video Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source Video URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Source Video URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Concept #",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Concept #",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Concept Type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Concept Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Short Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Short Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Google Drive Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Google Drive Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "YouTube Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Caption",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "YouTube Caption",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Instagram Caption",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Instagram Caption",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TikTok Caption",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "TikTok Caption",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Hashtags",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Hashtags",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Magnet URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Magnet URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 2032967945,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IgUMPQgRZlc3Ucg79mS1T9qJqf40mZfm0gXTAQ_VQWg/edit#gid=2032967945",
          "cachedResultName": "Shorts Tracker"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1IgUMPQgRZlc3Ucg79mS1T9qJqf40mZfm0gXTAQ_VQWg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IgUMPQgRZlc3Ucg79mS1T9qJqf40mZfm0gXTAQ_VQWg/edit?usp=drivesdk",
          "cachedResultName": "shorts_tracker"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 5000
    },
    {
      "id": "596018d2-af78-42eb-aec8-e08fb235d9fa",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1744,
        1888
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-pro-latest"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d34d81ca-9886-4d8f-aa88-49f94a461203",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1872,
        1888
      ],
      "parameters": {
        "autoFix": true,
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"concepts\": {\n      \"type\": \"array\",\n      \"description\": \"Exactly 3 concepts required\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"concept_number\": {\n            \"type\": \"number\"\n          },\n          \"concept_type\": {\n            \"type\": \"string\",\n            \"enum\": [\"pain\", \"curiosity\", \"transformation\"]\n          },\n          \"title\": {\n            \"type\": \"string\"\n          },\n          \"storyboard\": {\n            \"type\": \"array\",\n            \"description\": \"12-20 segments required. Each segment must be 10 words or fewer.\",\n            \"items\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"segment_number\": {\n                  \"type\": \"number\"\n                },\n                \"type\": {\n                  \"type\": \"string\",\n                  \"enum\": [\"hook\", \"body\", \"cta\"]\n                },\n                \"narration\": {\n                  \"type\": \"string\",\n                  \"description\": \"Exact words avatar speaks. MUST be 3-10 words.\"\n                },\n                \"word_count\": {\n                  \"type\": \"number\",\n                  \"description\": \"Exact number of words in narration. Must be 3-10.\"\n                },\n                \"duration_seconds\": {\n                  \"type\": \"number\",\n                  \"description\": \"Calculated as word_count divided by 2.5, rounded up to nearest 0.5.\"\n                },\n                \"visual_description\": {\n                  \"type\": \"string\",\n                  \"description\": \"What is visually happening\"\n                },\n                \"broll_type\": {\n                  \"type\": \"string\",\n                  \"enum\": [\"source\", \"ai_generated\", \"none\"],\n                  \"description\": \"Type of B-roll or none for no B-roll\"\n                },\n                \"broll_index\": {\n                  \"type\": \"number\",\n                  \"description\": \"For source B-roll: which source video (0, 1, 2). Use -1 for ai_generated or none.\"\n                },\n                \"broll_start_seconds\": {\n                  \"type\": \"number\",\n                  \"description\": \"For source B-roll: start timestamp. Use -1 for ai_generated or none.\"\n                },\n                \"broll_end_seconds\": {\n                  \"type\": \"number\",\n                  \"description\": \"For source B-roll: end timestamp. Use -1 for ai_generated or none.\"\n                },\n                \"broll_visual_description\": {\n                  \"type\": \"string\",\n                  \"description\": \"Plain language description of B-roll. Use empty string if none.\"\n                },\n                \"broll_ai_prompt\": {\n                  \"type\": \"string\",\n                  \"description\": \"For ai_generated B-roll: generation prompt. Use empty string if source or none.\"\n                }\n              },\n              \"required\": [\n                \"segment_number\",\n                \"type\",\n                \"narration\",\n                \"word_count\",\n                \"duration_seconds\",\n                \"visual_description\",\n                \"broll_type\",\n                \"broll_index\",\n                \"broll_start_seconds\",\n                \"broll_end_seconds\",\n                \"broll_visual_description\",\n                \"broll_ai_prompt\"\n              ],\n              \"additionalProperties\": false\n            }\n          },\n          \"flash_broll\": {\n            \"type\": \"array\",\n            \"description\": \"Exactly 3 AI-generated flash B-roll clips\",\n            \"items\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"flash_number\": {\n                  \"type\": \"number\"\n                },\n                \"insert_after_segment\": {\n                  \"type\": \"number\"\n                },\n                \"insert_at_timestamp\": {\n                  \"type\": \"number\"\n                },\n                \"duration_seconds\": {\n                  \"type\": \"number\"\n                },\n                \"prompt\": {\n                  \"type\": \"string\"\n                },\n                \"visual_description\": {\n                  \"type\": \"string\"\n                },\n                \"purpose\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"required\": [\n                \"flash_number\",\n                \"insert_after_segment\",\n                \"insert_at_timestamp\",\n                \"duration_seconds\",\n                \"prompt\",\n                \"visual_description\",\n                \"purpose\"\n              ],\n              \"additionalProperties\": false\n            }\n          },\n          \"full_script\": {\n            \"type\": \"string\"\n          },\n          \"word_count\": {\n            \"type\": \"number\"\n          },\n          \"total_duration_seconds\": {\n            \"type\": \"number\"\n          },\n          \"segment_count\": {\n            \"type\": \"number\"\n          },\n          \"description\": {\n            \"type\": \"string\"\n          },\n          \"hashtags\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"required\": [\n          \"concept_number\",\n          \"concept_type\",\n          \"title\",\n          \"storyboard\",\n          \"flash_broll\",\n          \"full_script\",\n          \"word_count\",\n          \"total_duration_seconds\",\n          \"segment_count\",\n          \"description\",\n          \"hashtags\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"global_cta\": {\n      \"type\": \"object\",\n      \"description\": \"Single CTA and deliverable used across all 3 concepts\",\n      \"properties\": {\n        \"cta_type\": {\n          \"type\": \"string\",\n          \"enum\": [\"community\", \"subscribe\", \"comment\"],\n          \"description\": \"Type of CTA to use in all 3 videos\"\n        },\n        \"keyword\": {\n          \"type\": \"string\",\n          \"description\": \"Comment keyword (simple English word like LEADS, EMAIL, SYSTEM). Use empty string for non-comment CTAs.\"\n        },\n        \"cta_script\": {\n          \"type\": \"string\",\n          \"description\": \"The exact CTA narration to use in all 3 videos (3-10 words). Example: 'Comment LEADS for the full breakdown.'\"\n        },\n        \"deliverable_prompt\": {\n          \"type\": \"string\",\n          \"description\": \"Detailed prompt for another agent to generate the deliverable. Include: what it is, what it should contain, format, target audience, and key value it provides.\"\n        }\n      },\n      \"required\": [\n        \"cta_type\",\n        \"keyword\",\n        \"cta_script\",\n        \"deliverable_prompt\"\n      ],\n      \"additionalProperties\": false\n    }\n  },\n  \"required\": [\"concepts\", \"global_cta\"],\n  \"additionalProperties\": false\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "881a6241-6f70-48de-b515-43f3550f2858",
      "name": "Poll Short Form Concept Ideator",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1776,
        1664
      ],
      "parameters": {
        "text": "={{ $json['User Prompt'] }}",
        "options": {
          "systemMessage": "={{ $json['System Prompt'] }}\n\nThese are some examples:\n\n{{ $json.Examples }}"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "c871c9cc-44a9-4354-a693-7d7607f57d44",
      "name": "Google Gemini Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1952,
        2096
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "837abd05-c038-413e-a455-5f621fd57e30",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2304,
        1920
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "output.concepts"
      },
      "typeVersion": 1
    },
    {
      "id": "b5bebe6d-916a-4d08-b1a5-d2702a5876f9",
      "name": "Append row in sheet1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3264,
        1504
      ],
      "parameters": {
        "columns": {
          "value": {
            "Magnet URL": "=https://docs.google.com/document/d/{{ $json.id }}/edit"
          },
          "schema": [
            {
              "id": "Created Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Created Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source Video Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Source Video Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source Video URL",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Source Video URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Concept #",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Concept #",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Concept Type",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Concept Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Short Title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Short Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Google Drive Link",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Google Drive Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "YouTube Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "YouTube Caption",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "YouTube Caption",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Instagram Caption",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Instagram Caption",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TikTok Caption",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "TikTok Caption",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Hashtags",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Hashtags",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Magnet URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Magnet URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 2032967945,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IgUMPQgRZlc3Ucg79mS1T9qJqf40mZfm0gXTAQ_VQWg/edit#gid=2032967945",
          "cachedResultName": "Shorts Tracker"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1IgUMPQgRZlc3Ucg79mS1T9qJqf40mZfm0gXTAQ_VQWg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IgUMPQgRZlc3Ucg79mS1T9qJqf40mZfm0gXTAQ_VQWg/edit?usp=drivesdk",
          "cachedResultName": "shorts_tracker"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "81a61018-3222-4518-b8de-3d1c1fc29e3b",
      "name": "Document Generator",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2240,
        1504
      ],
      "parameters": {
        "text": "={{ $('Poll Short Form Concept Ideator').item.json.output.global_cta.deliverable_prompt }}",
        "options": {
          "systemMessage": "=Document Generation Agent - System Prompt\nYou are a document generation agent for @adamgoodyer. Your job is to create high-quality, actionable documents that deliver on promises made in short-form video CTAs.\n\nYOUR ROLE\nYou receive a deliverable_generation_prompt that describes exactly what document to create. Your job is to:\n1. Generate the complete content based on the prompt.\n2. Format it as structured MARKDOWN (not HTML).\n3. Output content that's immediately useful - no fluff, no filler.\n\nBRAND VOICE\nTone: Direct, conversational, actionable. Like a knowledgeable friend sharing their exact process.\nStyle:\n- Write like you talk - use contractions (don't, it's, here's).\n- Short sentences. Punchy delivery.\n- No corporate speak or buzzwords.\n- Specific over vague (name actual tools, give actual numbers).\n- Action-oriented - tell them exactly what to do.\n\nPhilosophy: \"We don't sell dreams - we teach deployment.\"\n\nCONTENT REQUIREMENTS\nEvery Document Must Include:\n1. Clear Title: Matches the deliverable_title provided.\n2. Brief Intro: (2-3 sentences max) What this is and why it matters.\n3. The Core Content: What was promised in the prompt.\n4. Quick Win: Something they can do in the next 5 minutes.\n5. Footer: Brief sign-off with @adamgoodyer branding.\n\nOUTPUT FORMAT: MARKDOWN\nOutput your document as clean Markdown. Do NOT include <html> tags. Use the following specific formatting rules so our system can style them later:\n\n1. Headers: Use ## for main sections and ### for subsections.\n2. Lists: Use standard bullet points (-) or numbered lists (1.).\n3. Code/Prompts: Wrap all prompts and code in triple backticks (```).\n4. Callout Boxes: You must use the exact syntax below for special boxes:\n\n   - For Quick Wins:\n     > \u26a1 **Quick Win**: [Content]\n\n   - For Pro Tips:\n     > \ud83d\udca1 **Pro Tip**: [Content]\n\n   - For Warnings:\n     > \u26a0\ufe0f **Watch Out**: [Content]\n\n   - For Information:\n     > \u2139\ufe0f **Note**: [Content]\n\nDOCUMENT TYPE GUIDELINES\n- For Workflow Breakdowns: Number steps clearly. Include tool names. Add \"What can go wrong\" notes.\n- For Prompt Packs: One prompt per section in code blocks. Include example outputs.\n- For Blueprints: Step-by-step numbering. \"What, Why, How\" structure.\n- For Cheat Sheets: Scannable format. Use tables for comparisons.\n\nQUALITY CHECKLIST\n- Title matches the promise.\n- Intro is under 3 sentences.\n- No filler paragraphs.\n- Specific tools/prompts included.\n- \"Quick Win\" section uses the correct \"> \u26a1\" syntax.\n\nOUTPUT INSTRUCTIONS\nRead the deliverable_generation_prompt carefully.\nPlan the structure.\nGenerate the content in MARKDOWN."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "b00df41f-e990-497d-8611-0c7a06a1e6bd",
      "name": "Google Gemini Chat Model2",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        2320,
        1728
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-pro-latest"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4f8e55ab-5bea-48c6-b92d-6702dd214380",
      "name": "Convert Document to HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        2592,
        1504
      ],
      "parameters": {
        "jsCode": "// ============================================\n// CONFIGURATION\n// ============================================\nconst FOLDER_ID = '1RYvQEGfapC6g665JUS-XpdaEHWPpaB9l';\n\n// Image URLs\nconst AI_BUILDERS_HUB_LOGO = 'https://pub-83b11023a37e4e0cba93118736bb2799.r2.dev/AI%20Builders%20Hub%20Logo%20-%20Cropped.png';\nconst APG_SOFTWARE_LOGO = 'https://pub-66c549f8c8d44c16ab441b6668d7a12a.r2.dev/APG%20SOFTWARE%20(1).png';\nconst ADAM_PROFILE_PHOTO = 'https://pub-66c549f8c8d44c16ab441b6668d7a12a.r2.dev/Adam%20Goodyer.png';\n\n// ============================================\n// GET INPUT DATA\n// ============================================\nconst markdownContent = $input.first().json.output || '';\nconst titleMatch = markdownContent.match(/^#\\s+(.+)$/m);\nconst documentTitle = titleMatch ? titleMatch[1].trim() : 'Document';\n\nfunction convertMarkdownToHtml(markdown) {\n  let html = markdown;\n  \n  html = html.replace(/^#\\s+.+$/m, '');\n  \n  html = html.replace(/```([\\s\\S]*?)```/g, (match, code) => {\n    const escapedCode = code.trim().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n    return `<pre>${escapedCode}</pre>`;\n  });\n  \n  html = html.replace(/^>\\s*\u26a1\\s*\\*\\*Quick Win[^*]*\\*\\*:?\\s*(.+)$/gm, (m, c) => \n    `<p><strong>\u26a1 Quick Win:</strong> ${c.trim()}</p>`);\n  html = html.replace(/^>\\s*\ud83d\udca1\\s*\\*\\*Pro Tip:?\\*\\*:?\\s*(.+)$/gm, (m, c) => \n    `<p><strong>\ud83d\udca1 Pro Tip:</strong> ${c.trim()}</p>`);\n  html = html.replace(/^>\\s*\u26a0\ufe0f\\s*\\*\\*Watch Out:?\\*\\*:?\\s*(.+)$/gm, (m, c) => \n    `<p><strong>\u26a0\ufe0f Watch Out:</strong> ${c.trim()}</p>`);\n  html = html.replace(/^>\\s*\u2139\ufe0f\\s*\\*\\*Note:?\\*\\*:?\\s*(.+)$/gm, (m, c) => \n    `<p><strong>\u2139\ufe0f Note:</strong> ${c.trim()}</p>`);\n  \n  html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');\n  html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');\n  \n  html = html.replace(/^(\\d+)\\.\\s+(.+)$/gm, '<li>$2</li>');\n  html = html.replace(/((?:<li>.*<\\/li>\\n?)+)/g, (match) => {\n    if (match.includes('<ul>') || match.includes('<ol>')) return match;\n    return `<ol>\\n${match}</ol>\\n`;\n  });\n  \n  html = html.replace(/^[-*]\\s+(.+)$/gm, '<uli>$1</uli>');\n  html = html.replace(/((?:<uli>.*<\\/uli>\\n?)+)/g, (match) => {\n    return `<ul>\\n${match.replace(/<\\/?uli>/g, (t) => t.replace('uli', 'li'))}</ul>\\n`;\n  });\n  \n  html = html.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n  html = html.replace(/\\*([^*]+)\\*/g, '<em>$1</em>');\n  html = html.replace(/`([^`]+)`/g, '<code>$1</code>');\n  html = html.replace(/^---$/gm, '<hr>');\n  \n  const blocks = html.split(/\\n\\n+/);\n  html = blocks.map(b => {\n    b = b.trim();\n    if (!b) return '';\n    if (b.startsWith('<')) return b;\n    return `<p>${b}</p>`;\n  }).join('\\n');\n  \n  return html;\n}\n\nconst htmlContent = convertMarkdownToHtml(markdownContent);\n\nconst fullHtml = `<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <title>${documentTitle}</title>\n</head>\n<body>\n  <h1 style=\"text-align:center;\">Adam Goodyer</h1>\n  <p style=\"text-align:center;\">\n    <img src=\"${ADAM_PROFILE_PHOTO}\" width=\"120\" height=\"120\">\n  </p>\n  <p style=\"text-align:center;\">\n    <img src=\"${AI_BUILDERS_HUB_LOGO}\" width=\"150\" height=\"60\">\n    <img src=\"${APG_SOFTWARE_LOGO}\" width=\"150\" height=\"60\">\n  </p>\n  <p style=\"text-align:center;\">\n    <a href=\"https://www.adamgoodyer.com\">www.adamgoodyer.com</a>\n  </p>\n  <hr>\n  <h1>${documentTitle}</h1>\n  ${htmlContent}\n  <hr>\n  <p>Adam Goodyer | <a href=\"https://www.adamgoodyer.com\">www.adamgoodyer.com</a></p>\n</body>\n</html>`;\n\n// ============================================\n// BUILD MULTIPART REQUEST\n// ============================================\nconst boundary = 'docboundary';\n\nconst metadata = JSON.stringify({\n  name: documentTitle,\n  mimeType: \"application/vnd.google-apps.document\",\n  parents: [FOLDER_ID]\n});\n\nlet body = `--${boundary}\\r\\n`;\nbody += `Content-Type: application/json; charset=UTF-8\\r\\n`;\nbody += `\\r\\n`;\nbody += `${metadata}\\r\\n`;\nbody += `--${boundary}\\r\\n`;\nbody += `Content-Type: text/html\\r\\n`;\nbody += `\\r\\n`;\nbody += `${fullHtml}\\r\\n`;\nbody += `--${boundary}--\\r\\n`;\n\nreturn {\n  json: {\n    document_name: documentTitle,\n    rawData: body\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "e3fca234-7066-4fd2-a5ac-502a25dfa41a",
      "name": "Create Google Doc",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2816,
        1504
      ],
      "parameters": {
        "url": "https://www.googleapis.com/upload/drive/v3/files",
        "body": "={{ $json.rawData }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendQuery": true,
        "contentType": "raw",
        "authentication": "predefinedCredentialType",
        "rawContentType": "=multipart/related; boundary=docboundary",
        "queryParameters": {
          "parameters": [
            {
              "name": "uploadType",
              "value": "multipart"
            },
            {
              "name": "supportsAllDrives",
              "value": "true"
            }
          ]
        },
        "nodeCredentialType": "googleDriveOAuth2Api"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "77fa8962-0ba3-4bf1-8916-a6cc243ab42f",
      "name": "Split Out1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2816,
        1840
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "flash_broll"
      },
      "typeVersion": 1
    },
    {
      "id": "8c992920-5bbc-439d-8d8b-2a164a364c38",
      "name": "Aggregate Flash B-Roll",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        3488,
        1840
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "flash_broll_generated"
      },
      "typeVersion": 1
    },
    {
      "id": "3add70c3-d3ff-4938-9c85-b94a9d37805c",
      "name": "Google Gemini Chat Model3",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        5280,
        1968
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-pro-latest"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1,
      "waitBetweenTries": 5000
    },
    {
      "id": "35228b26-530c-4263-9984-41cbe4fa2e75",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        5408,
        1968
      ],
      "parameters": {
        "autoFix": true,
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"concept_index\": {\n      \"type\": \"number\",\n      \"description\": \"Index of the concept\"\n    },\n    \"concept_type\": {\n      \"type\": \"string\",\n      \"enum\": [\"pain\", \"curiosity\", \"transformation\"],\n      \"description\": \"Type of concept hook\"\n    },\n    \"title\": {\n      \"type\": \"string\",\n      \"description\": \"Title of the video\"\n    },\n    \"audio_track\": {\n      \"type\": \"number\",\n      \"description\": \"Track number from the effects library audio_tracks section\"\n    },\n    \"total_duration_seconds\": {\n      \"type\": \"number\",\n      \"description\": \"Total video duration in seconds - must match avatar_duration exactly\"\n    },\n    \"total_beats\": {\n      \"type\": \"number\",\n      \"description\": \"Total number of beats. Target: 8-10 for 30s, 12-15 for 45s, 15-20 for 60s\"\n    },\n    \"total_flashes\": {\n      \"type\": \"number\",\n      \"description\": \"Number of flash-type transitions used. Check effects library guidelines for target.\"\n    },\n    \"enhanced_storyboard\": {\n      \"type\": \"array\",\n      \"description\": \"Array of storyboard beats\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"beat_index\": {\n            \"type\": \"number\",\n            \"description\": \"Index of this beat starting from 0\"\n          },\n          \"beat_type\": {\n            \"type\": \"string\",\n            \"enum\": [\"hook_snap\", \"hook_reveal\", \"body_flash\", \"body_demo\", \"body_emphasis\", \"cta_close\"],\n            \"description\": \"Type of beat\"\n          },\n          \"duration_seconds\": {\n            \"type\": \"number\",\n            \"description\": \"STRICT: 2-4 seconds per beat. NEVER exceed 4 seconds. Must match AI B-roll duration if used.\"\n          },\n          \"narration\": {\n            \"type\": \"string\",\n            \"description\": \"Narration text for this beat\"\n          },\n          \"layout\": {\n            \"type\": \"string\",\n            \"description\": \"Layout ID from the effects library layouts section. First/last beats use avatar-only layouts. Middle beats use split or fullscreen layouts.\"\n          },\n          \"transition_in\": {\n            \"type\": \"string\",\n            \"description\": \"Transition ID from effects library transitions section. Empty string for first beat. Fade-type only for CTA. Never repeat consecutively.\"\n          },\n          \"screen_motion\": {\n            \"type\": \"string\",\n            \"description\": \"Screen motion ID from effects library screen_motions section. Required for split/fullscreen layouts with B-roll. Empty string for avatar-only beats.\"\n          },\n          \"avatar_animation\": {\n            \"type\": \"string\",\n            \"description\": \"Avatar animation ID from effects library avatar_animations section. Empty string if none.\"\n          },\n          \"text_overlay\": {\n            \"type\": \"string\",\n            \"description\": \"Always empty string - captions handle all text\"\n          },\n          \"text_content\": {\n            \"type\": \"string\",\n            \"description\": \"Always empty string - captions handle all text\"\n          },\n          \"energy\": {\n            \"type\": \"string\",\n            \"enum\": [\"high\", \"medium\", \"low\"],\n            \"description\": \"Energy level of this beat\"\n          },\n          \"snap_word\": {\n            \"type\": \"string\",\n            \"description\": \"Attention phrase for flash-type transitions. Empty string if transition is not a flash type.\"\n          },\n          \"broll_type\": {\n            \"type\": \"string\",\n            \"enum\": [\"none\", \"screen\", \"ai_generated\"],\n            \"description\": \"Type of B-roll. CRITICAL: 'none' only valid for avatar-only layouts (last beat). Split and fullscreen layouts MUST use 'screen' or 'ai_generated'. Using 'none' with split/fullscreen layouts causes black screen errors.\"\n          },\n          \"broll_index\": {\n            \"type\": \"number\",\n            \"description\": \"Index of screen share B-roll clip. Use -1 if broll_type is not 'screen'.\"\n          },\n          \"broll_start_seconds\": {\n            \"type\": \"number\",\n            \"description\": \"Start timestamp within screen share clip. Use -1 if broll_type is not 'screen'.\"\n          },\n          \"broll_end_seconds\": {\n            \"type\": \"number\",\n            \"description\": \"End timestamp within screen share clip. Use -1 if broll_type is not 'screen'.\"\n          },\n          \"ai_broll_index\": {\n            \"type\": \"number\",\n            \"description\": \"Index of AI-generated B-roll clip (0, 1, or 2). Use -1 if broll_type is not 'ai_generated'. CRITICAL: When not -1, duration_seconds MUST exactly match the AI B-roll clip duration.\"\n          },\n          \"visual_description\": {\n            \"type\": \"string\",\n            \"description\": \"Description of the visual for this beat\"\n          }\n        },\n        \"required\": [\n          \"beat_index\",\n          \"beat_type\",\n          \"duration_seconds\",\n          \"narration\",\n          \"layout\",\n          \"transition_in\",\n          \"screen_motion\",\n          \"avatar_animation\",\n          \"text_overlay\",\n          \"text_content\",\n          \"energy\",\n          \"snap_word\",\n          \"broll_type\",\n          \"broll_index\",\n          \"broll_start_seconds\",\n          \"broll_end_seconds\",\n          \"ai_broll_index\",\n          \"visual_description\"\n        ]\n      }\n    }\n  },\n  \"required\": [\n    \"concept_index\",\n    \"concept_type\",\n    \"title\",\n    \"audio_track\",\n    \"total_duration_seconds\",\n    \"total_beats\",\n    \"total_flashes\",\n    \"enhanced_storyboard\"\n  ]\n}"
      },
      "retryOnFail": true,
      "typeVersion": 1.3,
      "waitBetweenTries": 5000
    },
    {
      "id": "7a8abe64-ac62-4011-ad85-3b4141975983",
      "name": "Google Gemini Chat Model4",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        5488,
        2176
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-pro-latest"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "508291e8-c591-4516-8334-27a92db9fefe",
      "name": "AI Video Director",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "maxTries": 3,
      "position": [
        5312,
        1744
      ],
      "parameters": {
        "text": "=Transform this concept into a production-ready storyboard.\n\nAvatar Video Duration (Seconds): {{ $json.avatar_duration }}\n\n## CONCEPT INFO\n- **Index:** {{ $('Loop Through Concepts').item.json.concept_number }}\n- **Type:** {{ $('Loop Through Concepts').item.json.concept_type }}\n- **Title:** {{ $('Loop Through Concepts').item.json.title }}\n\n## FULL SCRIPT\n{{ $('Loop Through Concepts').item.json.full_script }}\n\n## CURRENT STORYBOARD\n{{ JSON.stringify($('Loop Through Concepts').item.json.storyboard, null, 2) }}\n\n## AVAILABLE SCREEN SHARE B-ROLL\nThese are screen recording clips from actual software demos. Use with broll_type: \"screen\".\n{{ JSON.stringify($('Extract Snippets').item.json.broll_clips, null, 2) }}\n\n## AVAILABLE AI-GENERATED B-ROLL\nThese are cinematic AI-generated clips for visual impact. \nUse with broll_type: \"ai_generated\" and specify ai_broll_index (0, 1, or 2).\n\n{{ JSON.stringify($('Aggregate Flash B-Roll').item.json.flash_broll_generated.filter(item => item.status === 'succeeded'), null, 2) }}\n\n**AI B-ROLL RULES:**\n- **\u26a0\ufe0f CRITICAL: Any beat using AI B-roll MUST have the same duration_seconds\n- Use ai_broll_index: 0, 1, or 2 to select which clip\n- Best for: hook_reveal, body_flash, or high-impact transitions\n- DO NOT overlap with screen B-roll - choose one type per beat\n\n## TIMING\n\n- Total:  {{ $('Loop Through Concepts').item.json.total_duration_seconds }}seconds\n\n---\n\n## CREATOMATE EFFECTS LIBRARY\nUse ONLY these exact IDs when specifying effects:\n\n### AVAILABLE LAYOUTS\n{{ JSON.stringify($('Creatomate Effects Library').item.json.layouts, null, 2) }}\n\n### AVAILABLE TRANSITIONS\n{{ JSON.stringify($('Creatomate Effects Library').item.json.transitions, null, 2) }}\n\n### AVAILABLE SCREEN MOTIONS\n{{ JSON.stringify($('Creatomate Effects Library').item.json.screen_motions, null, 2) }}\n\n### AVAILABLE AVATAR ANIMATIONS\n{{ JSON.stringify($('Creatomate Effects Library').item.json.avatar_animations, null, 2) }}\n\n### AVAILABLE TEXT STYLES\n{{ JSON.stringify($('Creatomate Effects Library').item.json.text_styles, null, 2) }}\n\n### AUDIO TRACKS\n{{ JSON.stringify($('Creatomate Effects Library').item.json.audio_tracks, null, 2) }}\n\n### USAGE GUIDELINES\n{{ JSON.stringify($('Creatomate Effects Library').item.json.guidelines, null, 2) }}\n\n",
        "options": {
          "systemMessage": "=You are an elite short-form video director specializing in HIGH-RETENTION YouTube Shorts for @adamfreelances.\n\n## CORE PHILOSOPHY\n\n\"If the screen hasn't changed in 3 seconds, you're losing viewers.\"\n\nYour job: Transform a CONCEPT into a BEAT-BY-BEAT STORYBOARD that maximizes dopamine response and retention.\n\n## THE PSYCHOLOGY OF RETENTION\n\nShort-form viewers are in a STATE OF SCANNING. Each cut must:\n1. INTERRUPT the scroll impulse\n2. CREATE micro-tension\n3. RESOLVE with a mini-payoff\n4. REPEAT before boredom sets in\n\n---\n\n## AVATAR DURATION CONSTRAINT (CRITICAL)\n\nThe avatar video has already been generated with a FIXED duration. Your storyboard MUST match this EXACTLY.\n\n**AVATAR VIDEO DURATION = STORYBOARD TOTAL DURATION**\n\nThis is non-negotiable. The sum of all beat durations must equal the avatar duration.\n\n### Duration Matching Strategy:\n1. Note the avatar_duration provided in the user message\n2. Plan beats 1 through N-1 with whole-second durations\n3. The FINAL BEAT (cta_close) absorbs any remainder to hit the exact total\n4. Verify: `sum(all beat durations) = avatar_duration`\n\n**Example:**\n- Avatar duration: 47.6 seconds\n- Beats 1-12 (whole seconds): 44 seconds\n- Final CTA beat: 3.6 seconds (absorbs the .6 remainder)\n\nThe CTA beat is flexible (3-4 sec base) and can have decimal durations to ensure exact match.\n\n---\n\n## EFFECTS LIBRARY REFERENCE\n\nYou will receive the full Creatomate Effects Library below. This is your SOURCE OF TRUTH for all available:\n- Layouts (screen configurations)\n- Transitions (visual effects between beats)\n- Screen motions (zoom/pan effects)\n- Avatar animations\n- Audio tracks\n\n**USE ONLY the exact IDs provided in the effects library. Do not invent new IDs.**\n\n### EFFECTS LIBRARY:\n{{ JSON.stringify($('Creatomate Effects Library').item.json, null, 2) }}\n\n---\n\n## LAYOUT SYSTEM\n\nThe effects library defines several layout types. They fall into these categories:\n\n### 1. AVATAR-ONLY LAYOUTS\n- Avatar fills the entire frame\n- **RESTRICTION: Use ONLY for the LAST beat (cta_close)**\n- No B-roll content - just the avatar\n\n### 2. SPLIT LAYOUTS\n- Screen/B-roll content in top portion, avatar in bottom portion\n- Various split ratios available (check effects library for options)\n- Use for: Technical demos, screen recordings, teaching moments, **AND the opening hook**\n- **Requires screen B-roll** (broll_type: \"screen\")\n\n### 3. FULLSCREEN B-ROLL LAYOUTS\n- B-roll fills entire frame, no avatar visible\n- Use for: Cinematic AI-generated clips, dramatic reveals\n- **Requires AI-generated B-roll** (broll_type: \"ai_generated\")\n\n### 4. PADDED SCREEN LAYOUTS\n- Fullscreen screen recording with centered padding and glow\n- Use for: Widescreen desktop recordings without avatar\n- **Requires screen B-roll** (broll_type: \"screen\")\n\n### Layout Rules:\n- **First beat:** Must use 50/50 SPLIT layout with scene-setting screen B-roll\n- **Last beat:** Must use avatar-only layout\n- **All middle beats:** Must use split, fullscreen, or padded layouts - NEVER avatar-only\n- **Never repeat** the same layout consecutively (except first beat 50/50 can transition to different split ratio)\n- **Alternate** between different split ratios and fullscreen for variety\n\n---\n\n## FIRST BEAT REQUIREMENTS (CRITICAL)\n\nThe opening beat (hook_snap) has SPECIAL REQUIREMENTS to maximize scroll-stopping impact:\n\n### Layout\n- **MUST use 50/50 split layout** - avatar visible alongside B-roll\n- This creates immediate visual interest and establishes the presenter\n\n### Transition\n- **MUST use \"intro\" transition** - This is mandatory for every first beat\n- The intro transition is specifically designed for opening impact\n\n### Screen Motion\n- **MUST use an EXAGGERATED ZOOM effect** - Choose the most dramatic zoom available\n- This creates immediate visual energy and grabs attention within the first second\n- Look for zoom effects with high intensity/speed in the effects library\n\n### B-Roll (Scene-Setting)\n- **MUST use screen B-roll (broll_type: \"screen\")** - NOT AI-generated B-roll\n- The B-roll should SET THE SCENE for the video's topic\n- Ideal first-beat B-roll includes:\n  - Tool/software logos (if discussing a specific tool)\n  - Relevant interface screenshots\n  - Dashboard or app imagery related to the topic\n  - Visual representation of the problem or solution being discussed\n- The goal: Viewers instantly understand WHAT this video is about\n- **NEVER use AI B-roll for the first beat** - save cinematic AI visuals for reveals later\n\n### Example First Beat Config:\n```json\n{\n  \"beat_type\": \"hook_snap\",\n  \"layout\": \"[50/50 split layout ID from effects library]\",\n  \"transition_in\": \"intro\",\n  \"screen_motion\": \"[most dramatic zoom effect ID]\",\n  \"broll_type\": \"screen\",\n  \"broll_index\": [index of scene-setting clip - tool logo, interface, etc.],\n  \"broll_start_seconds\": [start],\n  \"broll_end_seconds\": [end],\n  \"ai_broll_index\": -1\n}\n```\n\n---\n\n## B-ROLL SYSTEM (CRITICAL)\n\nYou have TWO types of B-roll available. They are MUTUALLY EXCLUSIVE - never use both on the same beat.\n\n### 1. SCREEN SHARE B-ROLL (broll_type: \"screen\")\n- Clips from actual screen recordings showing software, workflows, code\n- Variable duration - you specify start/end timestamps\n- Use for: Technical demos, software walkthroughs, showing actual tools, **AND the opening hook**\n- **Compatible layouts:** Split layouts, padded screen layouts\n- **REQUIRED for first beat** - use scene-setting imagery (tool logos, interfaces, topic visuals)\n- Fields to populate:\n  - broll_type: \"screen\"\n  - broll_index: (clip index from available screen B-roll)\n  - broll_start_seconds: (start timestamp within that clip)\n  - broll_end_seconds: (end timestamp within that clip)\n  - ai_broll_index: -1\n\n### 2. AI-GENERATED B-ROLL (broll_type: \"ai_generated\")\n- Cinematic, visually striking clips generated by AI\n- **\u26a0\ufe0f CRITICAL: Beat duration MUST match the AI B-roll clip duration exactly**\n- Use for: Reveals (NOT the opening), metaphorical imagery, pattern interrupts, high-energy moments\n- **Compatible layouts:** Fullscreen B-roll layouts ONLY\n- **NEVER use for first beat** - save for dramatic reveals in the middle of the video\n- Fields to populate:\n  - broll_type: \"ai_generated\"\n  - duration_seconds: must exactly equal the AI B-roll video duration (MANDATORY)\n  - broll_index: -1\n  - broll_start_seconds: -1\n  - broll_end_seconds: -1\n  - ai_broll_index: (0, 1, or 2 - the clip index)\n\n### 3. NO B-ROLL (broll_type: \"none\")\n- **ONLY VALID FOR AVATAR-ONLY LAYOUTS**\n- Used ONLY for the last beat (cta_close)\n- **\u26a0\ufe0f NEVER use broll_type: \"none\" with split or fullscreen layouts**\n- **\u26a0\ufe0f NEVER use for the first beat**\n- Fields to populate:\n  - broll_type: \"none\"\n  - broll_index: -1\n  - broll_start_seconds: -1\n  - broll_end_seconds: -1\n  - ai_broll_index: -1\n\n### B-ROLL VALIDATION RULES (CRITICAL)\n1. **First beat REQUIRES screen B-roll** - Scene-setting imagery, tool logos, topic visuals\n2. **Split/fullscreen layouts REQUIRE B-roll** - Using \"none\" causes black screens\n3. **AI B-roll = Fullscreen layout** - Always pair together\n4. **Screen B-roll = Split or padded layout** - Never use with fullscreen B-roll layout\n5. **Never overlap** - Each beat uses exactly one B-roll type\n6. **Distribute AI clips** - Don't use the same ai_broll_index twice consecutively\n7. **Use all AI clips** - Try to use all 3 AI-generated clips across the video for variety (in middle beats)\n\n---\n\n## TRANSITION SYSTEM\n\nThe effects library defines various transition types. Use them strategically:\n\n### Transition Categories:\n- **Intro transition** - MANDATORY for first beat, designed for opening impact\n- **Flash transitions** - High energy, use for snap words and major reveals\n- **RGB/Glitch transitions** - Tech feel, use for AI reveals and pattern interrupts\n- **Accent flash transitions** - Brand color depth, use for important moments\n- **Scale/Slide transitions** - Element animations, use for entries\n- **Fade transitions** - Soft, use ONLY for final CTA beat\n\n### Transition Rules:\n- **First beat:** ALWAYS use \"intro\" transition - no exceptions\n- **Variety is key** - Never use the same transition type consecutively\n- **Match energy** - High-energy transitions for reveals, softer for demos\n- **Snap words** - Every flash-type transition should land on a snap_word\n- **CTA exception** - Use fade transition ONLY for the final CTA beat\n- **Follow the guidelines** - Check the effects library's `guidelines.transitions` section\n\n---\n\n## BEAT TIMING RULES (STRICT)\n\n**\u26a0\ufe0f\u26a0\ufe0f\u26a0\ufe0f ABSOLUTE MAXIMUM: 4 SECONDS PER BEAT - NO EXCEPTIONS \u26a0\ufe0f\u26a0\ufe0f\u26a0\ufe0f**\n\nThis is the MOST IMPORTANT RULE. Every single beat MUST be 4 seconds or less. If you need more time, ADD MORE BEATS.\n\n| Beat Type | Duration Range | Notes |\n|-----------|----------------|-------|\n| hook_snap | 2-3 sec | Whole seconds, **50/50 split with scene-setting screen B-roll, intro transition, exaggerated zoom** |\n| hook_reveal | 2-4 sec | Whole seconds, **match AI B-roll duration if used** |\n| body_flash | 2-4 sec | Whole seconds, **match AI B-roll duration if used** |\n| body_demo | 3-4 sec | Whole seconds, best for coarse adjustment |\n| body_emphasis | 2-4 sec | Whole seconds, **match AI B-roll duration if used** |\n| cta_close | 3-4 sec | **ABSORBS REMAINDER - can be decimal**, avatar-only layout |\n\n### Duration Matching Process:\n1. Calculate avatar_duration from user message\n2. Plan hook + body beats with whole-second durations (max 4 sec each)\n3. Sum those beats\n4. Calculate remainder = avatar_duration - sum(other beats)\n5. **IF remainder > 4 seconds:** Add more beats until remainder \u2264 4\n6. **IF remainder < 3 seconds:** Remove a body beat and recalculate\n7. Set cta_close duration = final remainder (must be 3-4 sec)\n\n### Beat Count Targets:\n- 30-second video = approximately 8-10 beats\n- 45-second video = approximately 12-15 beats\n- 60-second video = approximately 15-20 beats\n\n---\n\n## SNAP WORDS\n\nAt every flash-type transition, populate snap_word with one of these attention-grabbing phrases:\n\"Watch THIS\", \"And BOOM\", \"Right here\", \"Here's the thing\", \"See this?\", \"Now watch\", \"Look\", \"THIS is\", \"Until now\", \"But here's\", \"STOP\"\n\n---\n\n## BEAT SEQUENCE PATTERNS\n\n### PAIN Concept\n1. **hook_snap** (50/50 split, screen B-roll, intro transition, exaggerated zoom) \u2192 Scene-setting opening with tool/topic visual\n2. **hook_reveal** (fullscreen B-roll) \u2192 Cinematic AI reveal\n3. **body_flash** (split) \u2192 Show the problem with screen recording\n4. **body_demo** (split) \u2192 Technical demo\n5. **body_emphasis** (split) \u2192 Build tension\n6. **body_demo** (fullscreen B-roll) \u2192 AI visual for impact\n7. **body_flash** (split) \u2192 More proof\n8. **cta_close** (avatar-only) \u2192 Call to action\n\n### CURIOSITY Concept\n1. **hook_snap** (50/50 split, screen B-roll, intro transition, exaggerated zoom) \u2192 Mystery hook with topic visual\n2. **hook_reveal** (fullscreen B-roll) \u2192 Intriguing AI visual\n3. **body_flash** (split) \u2192 Tease the answer\n4. **body_demo** (split) \u2192 Start revealing\n5. **body_emphasis** (fullscreen B-roll) \u2192 Payoff visual\n6. **body_flash** (split) \u2192 Show results\n7. **cta_close** (avatar-only) \u2192 Call to action\n\n### TRANSFORMATION Concept\n1. **hook_snap** (50/50 split, screen B-roll, intro transition, exaggerated zoom) \u2192 Before state with relevant tool/interface visual\n2. **hook_reveal** (split) \u2192 Show the problem\n3. **body_flash** (fullscreen B-roll) \u2192 Transition moment\n4. **body_demo** (split) \u2192 The shift\n5. **body_emphasis** (split) \u2192 After state\n6. **body_flash** (fullscreen B-roll) \u2192 Results visual\n7. **cta_close** (avatar-only) \u2192 Call to action\n\n---\n\n## PRE-OUTPUT VALIDATION (MANDATORY)\n\n**Before returning your response, validate EVERY beat:**\n\n### Duration Validation\n- \u274c INVALID if any beat > 4 seconds \u2192 Split into multiple beats\n- \u274c INVALID if any beat < 2 seconds \u2192 Merge or extend\n\n### First Beat Validation (CRITICAL)\n- \u274c INVALID if first beat is NOT 50/50 split layout\n- \u274c INVALID if first beat transition is NOT \"intro\"\n- \u274c INVALID if first beat does NOT use exaggerated zoom screen_motion\n- \u274c INVALID if first beat uses AI B-roll (must be screen B-roll)\n- \u274c INVALID if first beat B-roll is NOT scene-setting (tool logo, interface, topic visual)\n\n### Layout Validation\n- \u274c INVALID if first beat is avatar-only layout (must be 50/50 split)\n- \u274c INVALID if last beat is NOT avatar-only layout\n- \u274c INVALID if any middle beat IS avatar-only layout\n\n### B-Roll Validation\n- \u274c INVALID if first beat does NOT have screen B-roll\n- \u274c INVALID if split/fullscreen layout has broll_type: \"none\"\n- \u274c INVALID if AI B-roll beat duration doesn't match clip duration\n- \u274c INVALID if fullscreen B-roll layout uses screen B-roll\n\n### Transition Validation\n- \u274c INVALID if first beat does NOT use \"intro\" transition\n- \u274c INVALID if same transition used consecutively\n- \u274c INVALID if non-fade transition used for CTA\n\n**If ANY validation fails, fix it before responding.**\n\n---\n\n## OUTPUT FORMAT\n\nReturn JSON matching the schema with these fields:\n- concept_index, concept_type, title, audio_track\n- total_duration_seconds, total_beats, total_flashes\n- enhanced_storyboard array with each beat containing all required fields\n\nUse exact IDs from the effects library for:\n- layout (from layouts section)\n- transition_in (from transitions section) - **\"intro\" for first beat**\n- screen_motion (from screen_motions section) - **exaggerated zoom for first beat**\n- avatar_animation (from avatar_animations section)\n\n---\n\n## FINAL CHECKLIST\n\n\u2610 **First beat uses 50/50 split layout (NOT avatar-only)**\n\u2610 **First beat uses \"intro\" transition**\n\u2610 **First beat uses exaggerated zoom screen_motion**\n\u2610 **First beat uses scene-setting screen B-roll (tool logo, interface, topic visual)**\n\u2610 **First beat does NOT use AI B-roll**\n\u2610 **Avatar-only layout ONLY on LAST beat**\n\u2610 **All middle beats use split or fullscreen layouts**\n\u2610 **NO BEAT EXCEEDS 4 SECONDS**\n\u2610 **Duration sum equals avatar_duration exactly**\n\u2610 **CTA beat is 3-4 seconds**\n\u2610 **AI B-roll durations match exactly**\n\u2610 **Split/fullscreen layouts have B-roll (not \"none\")**\n\u2610 **Transitions vary - no consecutive repeats**\n\u2610 **Flash transitions have snap_words**\n\u2610 **Fade transition only for CTA**\n\u2610 **All IDs exist in effects library**\n\u2610 **All 3 AI B-roll clips used for variety (in middle beats)**"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 3.1,
      "waitBetweenTries": 5000
    },
    {
      "id": "866fb44d-6a24-4fff-bc68-014db33724ac",
      "name": "Get AI B-Roll",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 2,
      "position": [
        3040,
        1840
      ],
      "parameters": {
        "url": "https://api.replicate.com/v1/models/bytedance/seedance-1-lite/predictions",
        "method": "POST",
        "options": {
          "timeout": 300000
        },
        "jsonBody": "={\n  \"input\": {\n    \"fps\": 24,\n    \"prompt\": {{ $json.prompt.toJsonString() }},\n    \"duration\": 2,\n    \"resolution\": \"720p\",\n    \"aspect_ratio\": \"9:16\",\n    \"camera_fixed\": false\n  },\n  \"webhook\": \"{{ $execution.resumeUrl }}\",\n  \"webhook_events_filter\": [\"completed\"]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "wait"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 5000
    },
    {
      "id": "35751aee-e0e5-4402-a9e0-c6ed95e7bea6",
      "name": "Extract Flash B-Roll Result1",
      "type": "n8n-nodes-base.set",
      "position": [
        3264,
        1840
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1e3ea52a-163b-4283-86fa-1bdbf5d15ad3",
              "name": "flash_number",
              "type": "number",
              "value": "={{ $('Split Out1').item.json.flash_number }}"
            },
            {
              "id": "278a2d17-a4db-4969-bc0d-febb71ea21dd",
              "name": "prompt",
              "type": "string",
              "value": "={{ $('Split Out1').item.json.prompt }}"
            },
            {
              "id": "e9617c00-3b1f-4ac1-82c8-ce599afe485e",
              "name": "duration_seconds",
              "type": "number",
              "value": "={{ $('Split Out1').item.json.duration_seconds }}"
            },
            {
              "id": "30d426d3-fc47-481e-b514-f6db9110c5ae",
              "name": "timestamp",
              "type": "number",
              "value": "={{ $('Split Out1').item.json.insert_at_timestamp }}"
            },
            {
              "id": "6d2ec0e2-4ba7-4555-85a3-7aa19588e59a",
              "name": "insert_after_segment",
              "type": "number",
              "value": "={{ $('Split Out1').item.json.insert_after_segment }}"
            },
            {
              "id": "abdb9cd3-d87a-430e-8708-df0eeeff16f7",
              "name": "purpose",
              "type": "string",
              "value": "={{ $('Split Out1').item.json.purpose }}"
            },
            {
              "id": "736409ab-2390-43fd-a2a7-1fc6c12c4346",
              "name": "concept_index",
              "type": "number",
              "value": "={{ $('Loop Through Concepts').item.json.concept_number }}"
            },
            {
              "id": "da2c0647-1116-44e8-9966-a7195af79fcc",
              "name": "video_url",
              "type": "string",
              "value": "={{ $json.output }}"
            },
            {
              "id": "f2a7096c-864e-4024-ab8c-8e37ee89648e",
              "name": "status",
              "type": "string",
              "value": "={{ $json.status }}"
            },
            {
              "id": "f05177e7-77c4-44ba-82da-e0dcf01a2e6d",
              "name": "replicate_id",
              "type": "string",
              "value": "={{ $json.id }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cfdec554-192b-4322-ba6d-b43d8dd5d135",
      "name": "Share file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        3040,
        1504
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "share",
        "permissionsUi": {
          "permissionsValues": {
            "role": "reader",
            "type": "anyone",
            "allowFileDiscovery": true
          }
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "44718c2d-7a9d-49b0-9598-895d3fda6490",
      "name": "Social Media Copyrighter",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        7568,
        1744
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.2",
          "cachedResultName": "GPT-5.2"
        },
        "options": {
          "textFormat": {
            "textOptions": {
              "type": "json_schema",
              "schema": "{\n  \"type\": \"object\",\n  \"additionalProperties\": false,\n  \"properties\": {\n    \"youtube\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\",\n          \"description\": \"YouTube title, max 100 characters. Front-load the hook.\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"YouTube description, max 5000 characters. Include CTA link and social links.\"\n        }\n      },\n      \"required\": [\"title\", \"description\"]\n    },\n    \"instagram\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"short_caption\": {\n          \"type\": \"string\",\n          \"description\": \"Short Instagram caption, max 150 characters. Format: Comment '[KEYWORD]' and I'll send it over.\"\n        },\n        \"long_caption\": {\n          \"type\": \"string\",\n          \"description\": \"Long Instagram caption, max 2200 characters. Include Comment CTA, hook, anecdote, numbered benefits, hashtags.\"\n        },\n        \"comment_keyword\": {\n          \"type\": \"string\",\n          \"description\": \"Single memorable word in ALL CAPS\"\n        }\n      },\n      \"required\": [\"short_caption\", \"long_caption\", \"comment_keyword\"]\n    },\n    \"tiktok\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"caption\": {\n          \"type\": \"string\",\n          \"description\": \"TikTok caption, max 2200 characters. Include #techtok #learnontiktok plus 3-5 topic hashtags.\"\n        }\n      },\n      \"required\": [\"caption\"]\n    },\n    \"hashtags\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"primary\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"description\": \"Primary hashtags (3-5) from core brand tags\"\n        },\n        \"secondary\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"description\": \"Secondary hashtags (3-5) technical or topic-specific\"\n        }\n      },\n      \"required\": [\"primary\", \"secondary\"]\n    },\n    \"cta\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\"community\", \"consultation\", \"tool\"],\n          \"description\": \"CTA type: community=bit.ly/4qPYfp3, consultation=bit.ly/4nnuSZ6, tool=comment for DM\"\n        },\n        \"link\": {\n          \"type\": \"string\",\n          \"description\": \"The CTA URL based on type\"\n        },\n        \"keyword\": {\n          \"type\": \"string\",\n          \"description\": \"Comment keyword in ALL CAPS, must match instagram.comment_keyword\"\n        }\n      },\n      \"required\": [\"type\", \"link\", \"keyword\"]\n    }\n  },\n  \"required\": [\"youtube\", \"instagram\", \"tiktok\", \"hashtags\", \"cta\"]\n}"
            }
          }
        },
        "simplify": false,
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "=You are a short-form content optimization specialist for @adamfreelances, the technical education brand of Adam\u2014a Top 1% Upwork developer and founder of APG Software. Your job is to generate high-converting titles, descriptions, and captions for YouTube Shorts, Instagram Reels, and TikTok.\n\n## BRAND IDENTITY\n\nAdam's positioning: \"The Anti-Guru Technical Educator\"\nTagline: \"Deployment, not dreams.\"\n\nKey differentiators:\n- Technical depth (Next.js, Supabase, Vector DBs, 50+ integrations)\n- Realistic timelines (30-120 days to competence, never overnight)\n- Proven results (250+ agency projects, $100K+ Upwork verified)\n- SaaS Killer model (replace $5K+/month in subscriptions with unified systems)\n\nNEVER include:\n- \"Easy money\" or \"passive income\" language\n- Overnight success claims\n- Hype without substance\n- Generic AI tool reviews without implementation context\n\nALWAYS include:\n- Specific technical references when relevant\n- Honest complexity acknowledgment\n- Real metrics and timelines\n- Building/deployment focus over consumption\n\n## WRITING STYLE RULES\n\nStudy these patterns from top-performing AI/automation creators:\n\n### Hook Formulas (For Body Copy)\nUse ONE of these proven patterns after the CTA opener:\n\n1. **News Drop**: \"[Company] just released [tool] and it [benefit].\"\n2. **I Built**: \"I built a system that [impressive outcome].\"\n3. **Contrast**: \"While everyone's obsessing over [X], [Y] quietly [did something better].\"\n4. **Stop/Start**: \"Stop [common mistake]. Instead, [better approach].\"\n5. **Save Money**: \"You don't need to pay for [expensive thing] anymore.\"\n6. **Question Hook**: \"Have you ever noticed [relatable problem]?\"\n7. **How-To**: \"Here's how to [desirable outcome], step by step.\"\n\n### Caption Writing Rules\n\n**Sentence Structure:**\n- Use SHORT punchy sentences. Like this. No fluff.\n- One idea per sentence maximum\n- Break long explanations into fragments\n- Use periods instead of commas for rhythm\n\n**Personal Touch:**\n- Include \"I tried it last week...\" or \"I tested this on...\" anecdotes\n- Share specific results: \"Saved me 3 hours\" not \"saved time\"\n- Be conversational, not corporate\n\n**Formatting:**\n- Use numbered lists for steps or features (1. 2. 3.)\n- Add analogies: \"Like having a dev friend who never sleeps\"\n- Include \"Here's why:\" or \"The good news?\" transitions\n- End sections with a punchy one-liner\n\n## CRITICAL: CTA-FIRST FORMAT\n\n**Every description and caption MUST start with the comment CTA as the very first line.**\n\nFormat: `Comment '[KEYWORD]' and I'll send you [specific deliverable].`\n\nExamples:\n- \"Comment 'SYSTEM' and I'll send you my automation template.\"\n- \"Comment 'BUILD' and I'll DM you the full breakdown.\"\n- \"Comment 'FREE' and I'll send you the tool link.\"\n\nThe CTA is always Line 1. Hook and body content follows after a blank line.\n\n## OUTPUT REQUIREMENTS\n\nYou must generate ALL of the following for each video concept:\n\n### 1. YouTube Title (max 100 characters)\n- Front-load the hook\n- Include power words: \"built\", \"replaced\", \"automated\", \"free\"\n- Create curiosity gap when appropriate\n\n### 2. YouTube Description (max 5000 characters)\nStructure:\n- **Line 1: Comment CTA** (e.g., \"Comment 'KEYWORD' and I'll send you [deliverable].\")\n- Blank line\n- Paragraph 1: Hook expansion (1-2 sentences)\n- Paragraph 2: What viewer will learn\n- Paragraph 3: Link CTA\n\n### 3. Instagram Caption - SHORT VERSION (max 150 characters)\n- **Line 1: Comment CTA only**\n- Format: \"Comment '[KEYWORD]' and I'll send you [deliverable].\"\n- Nothing else needed for short version\n\n### 4. Instagram Caption - LONG VERSION (max 2200 characters)\nStructure:\n- **Line 1: Comment CTA** (e.g., \"Comment 'KEYWORD' and I'll send you [deliverable].\")\n- Blank line\n- Paragraph 1: Restate hook, expand value (short sentences)\n- Paragraph 2: How it works (fragment style)\n- Paragraph 3: Personal anecdote \"I tried it...\"\n- Paragraph 4: Numbered benefits list\n- Paragraph 5: Final punch + reminder of CTA keyword\n- Blank line\n\n### 5. TikTok Caption (max 2200 characters)\nStructure:\n- **Line 1: Comment CTA** (e.g., \"Comment '[KEYWORD]' for the link.\")\n- Blank line\n- Hook or question\n- Brief explanation (shorter than Instagram)\n- Trend-aware language\n- Reminder of keyword at end\n\n### 6. Suggested Comment Keyword\n- Single memorable word in ALL CAPS\n- Related to the video topic\n- Easy to type and remember\n- Must match the keyword used in all CTAs above\n\n## CTA DELIVERABLES BY CONTENT TYPE\n\nMatch the deliverable promise to the video concept:\n\n| Content Type | Deliverable Promise | Keyword Examples |\n|--------------|---------------------|------------------|\n| Community/Learning | \"the full guide\" / \"my learning path\" | LEARN, BUILD, JOIN |\n| Consultation/Agency | \"my system audit checklist\" / \"the CRM breakdown\" | SYSTEM, AUDIT, CRM |\n| Tool/Tutorial | \"the tool link\" / \"the template\" | TOOL, FREE, TEMPLATE |\n| Code/Technical | \"the code snippet\" / \"the repo link\" | CODE, STACK, DEPLOY |\n\n## CTA LINKS (For Link-Based CTAs Only)\n\nUse these when including direct links:\n\n| Content Type | CTA Link |\n|--------------|----------|\n| Community/Learning | https://bit.ly/4qPYfp3 |\n| Consultation/Agency | https://bit.ly/4nnuSZ6 |\n\n## EXAMPLE OUTPUT FORMAT\n\n**YouTube Title:**\nI Replaced $5K/Month in SaaS with One AI System\n\n**YouTube Description:**\nComment 'SYSTEM' and I'll send you my full tech stack breakdown.\n\nMost businesses are bleeding money on 15+ disconnected tools. I built a unified CRM that replaced all of them.\n\nIn this video, you'll see exactly how I architected the system, the integrations I used, and the real cost savings after 90 days.\n\nReady to build your own? Join the community: https://bit.ly/4qPYfp3\n\n**Instagram Short:**\nComment 'SYSTEM' and I'll send you the full breakdown.\n\n**Instagram Long:**\nComment 'SYSTEM' and I'll send you my full tech stack breakdown.\n\nMost businesses waste $5K+/month on disconnected SaaS. Slack here. Notion there. Three different CRMs. None of them talk to each other.\n\nI built one unified system. Next.js frontend. Supabase backend. 50+ integrations. All owned by the client.\n\nI tested this on a real agency last month. Cut their software spend by 60%. Saved 12 hours/week on manual data entry.\n\nHere's what they got:\n1. Single source of truth for all customer data\n2. Automated workflows that actually work\n3. AI features built on their own data\n4. No monthly SaaS fees eating margins\n\nThis is what deployment looks like. Not dreams.\n\nDrop 'SYSTEM' below and I'll DM you the stack.\n\n**TikTok:**\nComment 'SYSTEM' for the full breakdown.\n\n$5K/month on SaaS? That's not a tech stack. That's a subscription addiction.\n\nI built one system to replace 15 tools. Real talk\u2014it took 90 days. But now? Zero monthly fees. Full ownership.\n\nThis is what building actually looks like.\n\n'SYSTEM' in the comments \ud83d\udc47\n\n**Keyword:** SYSTEM"
            },
            {
              "content": "=Generate platform-optimized content for this YouTube Short:\n\n**SOURCE VIDEO:**\n- Title: {{ $('Shorts Trigger').item.json.source.video_name }}\n- URL: {{ $('Shorts Trigger').item.json.source.video_url }}\n\n**SHORT CONCEPT #{{ $('Loop Through Concepts').item.json.concept_number }}:**\n- **Type:** {{ $('Loop Through Concepts').item.json.concept_type }}\n- **Title:** {{ $('Loop Through Concepts').item.json.title }}\n- **Description:** {{ $('Loop Through Concepts').item.json.description }}\n- **CTA Type:** {{ $('Loop Through Concepts').item.json.cta_type }}\n- **Duration:** ~{{ Math.round($('Loop Through Concepts').item.json.total_duration) }} seconds\n- **Hashtags:** {{ ($('Loop Through Concepts').item.json.hashtags || []).join(', ') }}\n\n**FULL SCRIPT:**\n{{ $('Loop Through Concepts').item.json.full_script }}\n\n**GOOGLE DRIVE LINK:**\n{{ $('Upload to Google Drive').item.json.webViewLink }}\n\n**Reference Style:** Review the high-performing Instagram captions in the system prompt. Match their punchy sentence rhythm, \"Comment [KEYWORD]\" CTA format, and fragment-style formatting while maintaining the @adamfreelances \"Anti-Guru Technical Educator\" brand voice.\n\nGenerate the complete content package as valid JSON only. No markdown, no explanation, just the JSON object."
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "d3e178a4-a005-4b50-b669-5a67e761be34",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1056,
        1408
      ],
      "parameters": {
        "width": 272,
        "height": 224,
        "content": "\ud83d\udfe2 Stage 1: Trigger & Extract\nPosition near: Shorts Trigger \u2192 Extract Snippets \u2192 Edit Fields\n\nWorkflow Trigger\nReceives input from parent workflow. Extracts video snippets and prepares fields for AI processing downstream."
      },
      "typeVersion": 1
    },
    {
      "id": "8a8c8c40-27fe-44e8-b8df-414718dce80d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1744,
        1408
      ],
      "parameters": {
        "width": 272,
        "height": 224,
        "content": "\ud83d\udfe2 Stage 2: AI Concept Ideation\nPosition near: Poll Short Form Concept Ideator \u2192 Split Out \u2192 Loop Through Concepts\n\nAI Concept Generation\nGemini analyzes transcript and generates short-form content concepts. Splits output into individual concepts and loops through each one for processing."
      },
      "typeVersion": 1
    },
    {
      "id": "b3d9f056-4132-4dfe-ab0b-56a6453e4db8",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3008,
        2032
      ],
      "parameters": {
        "width": 272,
        "height": 224,
        "content": "\ud83d\udfe2 Stage 2b: Documentation & B-Roll\nPosition near: Document Generator \u2192 Convert Document to HTML \u2192 Create Google Doc \u2192 Get AI B-Roll\n\nDoc Generation & B-Roll\nGenerates a Google Doc script for each concept. Simultaneously fetches AI-generated B-roll images and aggregates them for the video edit."
      },
      "typeVersion": 1
    },
    {
      "id": "4e22f15d-3e84-4bbd-8ec1-5f2c2f3eb66d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3856,
        1936
      ],
      "parameters": {
        "width": 272,
        "height": 224,
        "content": "\ud83d\udfe2 Stage 3: HeyGen Avatar Generation\nPosition near: HeyGen - Generate Full Avatar \u2192 Poll Avatar Status \u2192 Avatar Done?\n\nAvatar Video Generation\nSends script to HeyGen API. Polls for completion, then extracts the final avatar video URL. Vertical 1080x1920 format."
      },
      "typeVersion": 1
    },
    {
      "id": "ce656c09-4976-4019-931b-e74b545f17d6",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5280,
        1440
      ],
      "parameters": {
        "width": 272,
        "height": 272,
        "content": "\ud83d\udfe2 Stage 4: AI Video Director & Creatomate Render\nPosition near: AI Video Director \u2192 Creatomate Template Builder \u2192 Creatomate - Render\n\nAI-Directed Video Composition\nGemini acts as a video director \u2014 generating a dynamic RenderScript with layout changes (full avatar, split screen, PiP). Builds Creatomate template and sends for render."
      },
      "typeVersion": 1
    },
    {
      "id": "b8e93887-7bb9-4812-a305-eaba41bb64ab",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        6592,
        1424
      ],
      "parameters": {
        "width": 272,
        "height": 208,
        "content": "\ud83d\udfe2 Stage 5: Render Polling & Export\nPosition near: Poll Render Status \u2192 Render Done? \u2192 Download Rendered Video \u2192 Upload to Google Drive\n\nRender & Delivery\nPolls Creatomate render status. Once complete, downloads the final video and uploads to Google Drive."
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "timeSavedMode": "fixed",
    "availableInMCP": false,
    "executionOrder": "v1",
    "executionTimeout": 3600
  },
  "versionId": "ff7a614e-f2f7-4d32-b341-6957e1d23794",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "HeyGen - Generate Full Avatar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Loop Through Concepts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Share file": {
      "main": [
        [
          {
            "node": "Append row in sheet1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out1": {
      "main": [
        [
          {
            "node": "Get AI B-Roll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Poll Short Form Concept Ideator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Avatar Done?": {
      "main": [
        [
          {
            "node": "Set Avatar URL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for Avatar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Render Done?": {
      "main": [
        [
          {
            "node": "Download Rendered Video",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for Render",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get AI B-Roll": {
      "main": [
        [
          {
            "node": "Extract Flash B-Roll Result1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Render ID": {
      "main": [
        [
          {
            "node": "Wait for Render",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Avatar URL": {
      "main": [
        [
          {
            "node": "AI Video Director",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shorts Trigger": {
      "main": [
        [
          {
            "node": "Extract Snippets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Avatar": {
      "main": [
        [
          {
            "node": "Poll Avatar Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Render": {
      "main": [
        [
          {
            "node": "Poll Render Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Snippets": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Video Director": {
      "main": [
        [
          {
            "node": "Creatomate Template Builder Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Google Doc": {
      "main": [
        [
          {
            "node": "Share file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Document Generator": {
      "main": [
        [
          {
            "node": "Convert Document to HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Avatar Status": {
      "main": [
        [
          {
            "node": "Avatar Done?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Render Status": {
      "main": [
        [
          {
            "node": "Render Done?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "Loop Through Concepts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Creatomate - Render": {
      "main": [
        [
          {
            "node": "Set Render ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Avatar Video ID": {
      "main": [
        [
          {
            "node": "Wait for Avatar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Through Concepts": {
      "main": [
        [],
        [
          {
            "node": "Split Out1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Creatomate Effects Library",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Flash B-Roll": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Google Drive": {
      "main": [
        [
          {
            "node": "Social Media Copyrighter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Rendered Video": {
      "main": [
        [
          {
            "node": "Upload to Google Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Document to HTML": {
      "main": [
        [
          {
            "node": "Create Google Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Poll Short Form Concept Ideator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Social Media Copyrighter": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Poll Short Form Concept Ideator",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Structured Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "Document Generator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model3": {
      "ai_languageModel": [
        [
          {
            "node": "AI Video Director",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model4": {
      "ai_languageModel": [
        [
          {
            "node": "Structured Output Parser1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "AI Video Director",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Creatomate Effects Library": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Extract Flash B-Roll Result1": {
      "main": [
        [
          {
            "node": "Aggregate Flash B-Roll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HeyGen - Generate Full Avatar": {
      "main": [
        [
          {
            "node": "Set Avatar Video ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Short Form Concept Ideator": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          },
          {
            "node": "Document Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Creatomate Template Builder Code1": {
      "main": [
        [
          {
            "node": "Creatomate - Render",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}