{
  "$mulmocast": { "version": "1.1" },
  "title": "マコロアニメ プロトタイプ",
  "description": "MulmoCastリミテッドアニメーションのテスト",
  "lang": "ja",
  "speechParams": {
    "provider": "openai",
    "speakers": {
      "macoro": {
        "voiceId": "nova",
        "displayName": { "ja": "マコロ" }
      }
    }
  },
  "beats": [
    {
      "speaker": "macoro",
      "text": "こんにちは！ぼくマコロだよ！今日はみんなに会えてうれしいな！",
      "image": {
        "type": "html_tailwind",
        "html": [
          "<div class='h-full w-full relative overflow-hidden' style='background: linear-gradient(135deg, #fce4ec 0%, #f8bbd0 30%, #e1bee7 60%, #bbdefb 100%);'>",
          "",
          "  <!-- 背景の浮遊パーティクル -->",
          "  <div id='p1' class='absolute w-4 h-4 rounded-full' style='background: rgba(255,255,255,0.6); left:10%; top:80%;'></div>",
          "  <div id='p2' class='absolute w-3 h-3 rounded-full' style='background: rgba(255,200,200,0.5); left:30%; top:85%;'></div>",
          "  <div id='p3' class='absolute w-5 h-5 rounded-full' style='background: rgba(200,200,255,0.5); left:70%; top:75%;'></div>",
          "  <div id='p4' class='absolute w-3 h-3 rounded-full' style='background: rgba(255,255,200,0.6); left:85%; top:90%;'></div>",
          "  <div id='p5' class='absolute w-4 h-4 rounded-full' style='background: rgba(200,255,200,0.5); left:50%; top:82%;'></div>",
          "",
          "  <!-- 背景の星 -->",
          "  <div id='star1' class='absolute text-4xl' style='left:15%; top:15%;'>✦</div>",
          "  <div id='star2' class='absolute text-3xl' style='left:80%; top:20%;'>✦</div>",
          "  <div id='star3' class='absolute text-2xl' style='left:60%; top:10%;'>✦</div>",
          "",
          "  <!-- マコロ本体 -->",
          "  <div id='macoro-container' class='absolute' style='bottom:5%; left:50%; transform:translateX(-50%);'>",
          "    <img id='macoro' src='https://raw.githubusercontent.com/receptron/mulmocast-media/main/characters/macoro.png' style='width:500px; filter:drop-shadow(0 10px 20px rgba(0,0,0,0.2));' />",
          "  </div>",
          "",
          "  <!-- 吹き出し -->",
          "  <div id='bubble' class='absolute' style='top:8%; right:8%; opacity:0;'>",
          "    <div class='bg-white rounded-3xl px-8 py-5 shadow-lg relative' style='max-width:380px;'>",
          "      <p id='bubble-text' class='text-2xl font-bold text-gray-700'></p>",
          "      <div class='absolute -bottom-3 left-12 w-6 h-6 bg-white transform rotate-45'></div>",
          "    </div>",
          "  </div>",
          "",
          "</div>"
        ],
        "script": [
          "const fullText = 'こんにちは！ぼくマコロだよ！\\n今日はみんなに会えてうれしいな！';",
          "",
          "function render(frame, totalFrames, fps) {",
          "  const t = frame / fps;",
          "  const macoro = document.getElementById('macoro-container');",
          "  const bubble = document.getElementById('bubble');",
          "  const bubbleText = document.getElementById('bubble-text');",
          "",
          "  // --- マコロの動き ---",
          "  // 登場: 下からバウンスイン (0-1秒)",
          "  let macoroY = 0;",
          "  if (t < 1.0) {",
          "    const p = t / 1.0;",
          "    const bounce = Math.sin(p * Math.PI) * 30;",
          "    macoroY = (1 - p) * 200 - bounce;",
          "  }",
          "",
          "  // 話している時のぴょこぴょこ (1秒以降)",
          "  if (t >= 1.0) {",
          "    const talkBounce = Math.sin(t * 8) * 8;",
          "    const talkTilt = Math.sin(t * 5) * 3;",
          "    macoroY = talkBounce;",
          "    macoro.style.transform = 'translateX(-50%) translateY(' + macoroY + 'px) rotate(' + talkTilt + 'deg)';",
          "  } else {",
          "    macoro.style.transform = 'translateX(-50%) translateY(' + macoroY + 'px)';",
          "  }",
          "",
          "  // --- 吹き出し ---",
          "  if (t >= 0.8) {",
          "    const bubbleP = Math.min((t - 0.8) / 0.3, 1);",
          "    const scale = 0.5 + bubbleP * 0.5;",
          "    bubble.style.opacity = bubbleP;",
          "    bubble.style.transform = 'scale(' + scale + ')';",
          "",
          "    // タイプライター効果",
          "    const textProgress = Math.min((t - 1.0) / 3.0, 1);",
          "    if (textProgress > 0) {",
          "      const charCount = Math.floor(textProgress * fullText.length);",
          "      bubbleText.innerHTML = fullText.substring(0, charCount).replace('\\n', '<br>');",
          "    }",
          "  }",
          "",
          "  // --- 背景パーティクル ---",
          "  for (let i = 1; i <= 5; i++) {",
          "    const p = document.getElementById('p' + i);",
          "    const speed = 0.3 + i * 0.15;",
          "    const sway = Math.sin(t * (1 + i * 0.3) + i) * 20;",
          "    const y = ((1 - ((t * speed * 0.1) % 1)) * 110) - 10;",
          "    p.style.top = y + '%';",
          "    p.style.transform = 'translateX(' + sway + 'px)';",
          "  }",
          "",
          "  // --- 背景の星キラキラ ---",
          "  for (let i = 1; i <= 3; i++) {",
          "    const star = document.getElementById('star' + i);",
          "    const twinkle = 0.3 + Math.sin(t * 3 + i * 2) * 0.7;",
          "    const starScale = 0.8 + Math.sin(t * 2 + i) * 0.3;",
          "    star.style.opacity = twinkle;",
          "    star.style.transform = 'scale(' + starScale + ')';",
          "    star.style.color = 'rgba(255,200,50,' + twinkle + ')';",
          "  }",
          "}"
        ],
        "animation": { "fps": 24 }
      },
      "duration": 6
    }
  ]
}
