---
title: "考察記事6本を YouTube の掛け合い動画にする ― 2本目は配膳ロボットの回"
slug: six-deep-dives-to-dialogue-videos
date: 2026-11-02
day: 429
meta_description: "サイトの考察記事から、経営者や PM が自分の仕事に置き換えられる6本を YouTube の考察回に選び、2本目の配膳ロボットの回（8分35秒）を作った。1本目の部品を写すだけでは画面が止まって見え、場面ごとに大きな動きを置いた。"
tags: [YouTube, 解説動画, 考察回, 配膳ロボット, AI音声, ElevenLabs, Gemini, ハコブくん, 生成AI, 考察記事]
series: "ひとり研究所の裏側"
---

サイト pixelstomotors.com の考察記事から、ロボットの導入を考える経営者・PM・開発者が自分の仕事に置き換えられて、作り手の言葉が記事に残っている6本を、YouTube の考察回（案内役のロボット「ハコブくん」と作り手の掛け合い動画）に選んだ。その2本目として、配膳ロボットの回「配膳ロボットが店に広がった理由は「賢さ」じゃなかった」（8分35秒・考察記事 LOG389 がもと）を作り、1本目の書き出しの部品を写しただけでは画面が止まって見えたので、場面ごとに大きな動きを1つ置く形に作り直した。

この回で良くなること・できるようになったことは、次の3つです。

- **残りの5本は、作り手の答えをもらえば声から作れる。** 6本の台本のたたき（下書き）を、別々の AI エージェントに並行で書かせました。1本あたり104〜152秒でした。書いたのとは別のエージェントが記事と1文ずつ突き合わせ、6本とも直し終えています。残りは、作り手の実感を聞く質問（6本で28問）への答えだけです
- **作り手の言葉と、Claude の整理を、画面で取り違えなくなった。** 突き合わせで、Claude の答えの文に「この見立ては、エイイチから」の判子を押している台本が3本見つかりました。判子は作り手の言葉にだけ押す、と決め直しました
- **書き出しの部品の直しが、次の回からそのまま使える。** 作り手のドット絵が声に合わせて弾むと、画面の下に隙間が見えていた所を直しました。紙のカードで1〜2文字だけ次の行に落ちる所は、区切りの位置を指定できるようにしました。マンガ風の絵は、4コマ『ハコブくん』の絵柄を参照に付けて作るようにしました。どれも動画のルールに書き足しています

前の手間は測っていないので、どれだけ時間が浮いたかは数字で言えません。台本のたたきを並行で書けたことで、6本を1本ずつ書くより待ち時間は短く済んでいます。

いちばん大きな直しは、確認用の動画を見た作り手の一言からでした。

> 今動画見直したけど、全体に動きがないね。前作った動画のフォーマット確認して作っている？背景画像も入れてないけど？

1本目の考察回（LOG427）の完成した動画を1秒ごとに調べると、1本目も背景は黒一色でした。違いは場面の作り方で、1本目は場面ごとに主役になる大きな動き（数え上げ・大きな文字が落ちてくる所）が1つありました。2本目は、小さな文字のカードを4〜5枚積む場面が続いていました。

| やったこと | なぜ | 結果 |
|---|---|---|
| 考察記事の中から6本を選んだ | 動画の目的（仕事につながる視聴者を集める）に合う記事を先に決めるため | LOG389・LOG412・DAY336・LOG406・LOG392・LOG375。LOG396 は外した |
| 6本の台本のたたきを並行で書いた | 1本ずつ書くと待ち時間が長いため | 1本あたり104〜152秒 |
| 別のエージェントに、記事と1文ずつ突き合わせさせた | 書いた本人では同じ見落としをするため | 6本で45か所を直した。判子の取り違えが3本 |
| 2本目「現場で扱えるか」に作り手の答えを入れた | 実感は Claude が作ると作り物に聞こえるため | 「感激した」「大型のお店から」を入れ、「おばちゃんたち」を言い換えた |
| 声を ElevenLabs で作った | ナレーションは AI 音声の決まり | 86文（ハコブくん62・作り手24）。約2,983字 |
| 脱線の絵を Gemini で作り直した | 作り手「マンガの絵はハコブくんの絵柄をベースに」 | 4コマ第105話を絵柄の参照に付けた |
| 書き出しを3回した | 読みと隙間（v2）、動きのなさ（v3）の指摘 | 8分35秒。動いている時間 12% → 13%（1本目は16%） |
| サムネイル・タイトル・概要欄を作った | YouTube に上げる一式をそろえるため | A案「賢さ、じゃなかった」に決まった |
| 縦長ショート3本を作った | 本編に人を連れてくる入口にするため | 22〜24秒。作り手の指摘で、ハコブくんの動きを3本とも作り直した |

下の図で、選んだ6本の役割と、1本目・v1・v3 の画面の動きの違いを見られます。記事を押すと、選んだ理由と見込む効果が出ます。

【図解】LOG429_six_picks.html

【画像】LOG429_01_hook_stamp.png 考察回2本目の冒頭。紙に大きく「99%」と「6回 人が駆けつける」、右に朱の判子「優秀？」、左下にハコブくん、右下に作り手のドット絵

【画像】LOG429_05_scene_v1_v3.png 同じ場面の v1 と v3。左の v1 は小さな文字のカードが4枚積まれ、右の v3 はテーブル番号のボタン4つと「ほぼ不要」の大きな文字


## 作業ログ ― 考察記事を選んでから、2本目を書き出し直すまで

ここから下は作業の記録です。効果は、測れた数字を「変わったこと」に書き、ほかは見込みです。視聴の数字は、YouTube に公開したあとにアナリティクスで確かめます。この記事を書いた時点で、動画はまだ公開していません。

### 考察回とは：ハコブくんが Claude 役、作り手がその相手の掛け合い動画

考察回（壁打ちの型）は、LOG427 で作った YouTube の動画の型です。考察記事は、作り手と Claude のやり取りで考えが動いていく記録です。考察回では、その動きを、ハコブくん（Claude 役・まじめすぎるボケ）と作り手（ツッコミ兼本音）の掛け合いで見せます。

| 言葉 | この記事での意味 |
|---|---|
| 考察記事 | サイトの記事のうち、作り手と Claude の対話で考えたことを、対話のまま残した記事（シリーズ「考察記事」） |
| 台本のたたき | 声を作る前の下書きの台本。作り手のセリフ・相づち・脱線の絵・表情の割り当てまで書く |
| 【本人】 | 台本の中の、作り手が記事の中で言った言葉。話し言葉に整えるが、中身は足さない |
| 【相づち】 | Claude が書いた短い反応。作り手が採るかを選ぶ（この回は6本とも「採っていい」） |
| 脱線の場面 | 紙が飛んでいき、画面いっぱいの絵に替わる3〜5秒の場面 |
| 判子 | 紙の上に押す朱の札（ボツ・この見立ては、エイイチから など） |

### 6本の選び方：仕事に置き換えられること・本人の言葉が残っていること

サイトのシリーズ「考察記事」は8本です。LOG424 は1本目の考察回にしたので、残りの7本から選びました。選んだ基準は4つです。

1. **見る人が自分の仕事に置き換えられる。** チャンネルが集めたいのは、ロボットの導入を考える経営者・PM・マネージャー・開発者です。技術の話でも「うちの店」「うちの現場」に置き換えられる問いを選びました
2. **記事に作り手の言葉が残っている。** 考察回では、作り手のセリフは記事の中の本人の言葉から作ります。Claude が作ったセリフは作り物に聞こえます
3. **考えが動いた所がある。** 「最初はこう思ったが、調べたら違った」という転換があれば、ニュースのように事実を並べなくても山場が作れます
4. **作り手の立ち位置が出る。** 作り手は、ロボットを作る側より、店や現場に入れて回す側（シミュレーションとソフトの側）に立っています。見立てにそれが出れば、見た人が「この人に相談できそう」と思いやすくなります

| 順 | 記事 | 動画名（仮） | 紙に書く問い | 役割 |
|---|---|---|---|---|
| 1 | LOG389 | 現場で扱えるか | ロボットが店に広がるかを決めるのは、賢さか。 | 入口（だれでも分かる） |
| 2 | LOG412 | 照明で崩れるピッキング | 照明が変わると、ロボットはなぜ掴めないのか。 | 入口 |
| 3 | DAY336 | 成功の定義 | ロボットに動きを教えなくなったら、人は何を教えるのか。 | 技術の信頼 |
| 4 | LOG406 | どこまでいじっていい | メーカーのロボットは、どこまで変えられるか。 | 仕事につながる |
| 5 | LOG392 | 人のお手本の先へ | お手本をまねるだけで、ロボットは上達するか。 | 技術の信頼 |
| 6 | LOG375 | 安いアームを買う前に | 安いロボットアームは、買えば使えるのか。 | 仕事につながる |

外したのは LOG396（Physical Intelligence の π0.5 と Runpod と Claude Code を選ぶ理由）です。道具を選ぶ話で、開発者には刺さりますが、経営者・PM には遠く、掛け合いの笑いも作りにくいためです。技術の信頼の役割は、DAY336 と LOG392 で足りています。

- ねらい：入口の回で見る人を広げ、技術の回で信頼を積み、仕事の回で相談の入口を見せる順にする
- 変わったこと：6本の順番と役割を、作る前に決めた
- 見込める効果：見込みです。公開後、動画から元の記事への閲覧（サイトの閲覧の記録）と、相談の連絡で確かめる

LOG392 は LOG424（失敗の手直しの話）と中身が近いので、続けて出さず、間に別の回を挟みます。LOG389 は、前に作った解説回「日本で広がらない理由」と普及の話で近いので、台本は「現場で扱えるか」に絞りました。

### 台本のたたき：6本を別々のエージェントに並行で書かせた

6本は、1本ずつ別の AI エージェントに書かせました。どのエージェントにも同じ決まりを渡しています。

- 構成は1本目の台本のたたき（LOG424）と同じ。共通の決まりの節は書かず、参照の1行にする
- 【本人】は、記事の中の作り手の発言を話し言葉に整えたものだけ。行末に、記事の何番目の見出しの発言かを書く
- 数字は1回のやり取りに1つ。記事にある数字だけを使う
- 冒頭は数字か意外な一言で引き付ける。ボケはハコブくん
- 1本目の天丼（考え中の秒数・毎晩転ぶ）は丸写ししない

書けたたたきの大きさと、作り手のセリフの数は次のとおりです（字数はファイルのバイト数で、照合の直し前）。

| 動画名 | 大きさ | 【本人】 | 見立て帳 | 【相づち】 | 聞きたいこと | 書いた時間 |
|---|---|---|---|---|---|---|
| 現場で扱えるか | 17,351 | 12 | 1 | 8 | 4問 | 152秒 |
| 照明で崩れるピッキング | 19,050 | 13 | 0 | 8 | 5問 | 144秒 |
| 成功の定義 | 17,258 | 9 | 1 | 11 | 5問 | 130秒 |
| どこまでいじっていい | 16,175 | 5 | 1 | 8 | 5問 | 104秒 |
| 人のお手本の先へ | 17,449 | 5 | 1 | 12 | 4問 | 138秒 |
| 安いアームを買う前に | 18,977 | 11 | 0 | 8 | 5問 | 122秒 |

見立て帳は、作り手が記事の外で話した見立てを集めたファイル（`_制作ベース/エイイチの見立て帳.md`）と、記憶に残した作り手の考えです。記事の題材に直接つながるものだけを使いました。

天丼（くり返しの笑い）は回ごとに作り直しています。2本目「現場で扱えるか」は、ハコブくんが固まると頭の上に「再開」のボタンが出て、作り手が押して戻す流れです。最後だけハコブくんが自分で押します。「照明で崩れるピッキング」は、照明が変わるとハコブくんが作り手を見分けられなくなる流れにしました。

### 記事との突き合わせ：6本で45か所を直し、判子の取り違えが3本あった

書いたのとは別のエージェント2つに、3本ずつ、台本と記事を1文ずつ突き合わせさせました（1つにかかった時間は121秒と125秒）。指摘は、食い違い・根拠のない事実・言い過ぎ・【本人】に中身が足されている所の4つに分けて出させています。

| 動画名 | 直した数 | おもな指摘 |
|---|---|---|
| 現場で扱えるか | 8 | Claude の整理に判子を押していた／ボトルネックは「紙パック」ではなく「運用を直し続ける担い手がいないこと」／【本人】の前半が Claude の文の引用だった |
| 照明で崩れるピッキング | 6 | 照明が原因というのは発表した人たちの説明／「動作範囲を決めた中で」の前提が落ちていた |
| 成功の定義 | 11 | 本人は最初から「シミュレーション」と言っていた／同じチームが実機で組む映像がある／17.8% は条件付きの値／判子が Claude の言葉に押されていた |
| どこまでいじっていい | 7 | 判子が Claude の見立てに押されていた／改造の責任を一般化していた／車の改造の言い方 |
| 人のお手本の先へ | 7 | 手作り版にあたるのは残差強化学習だった／「1cm・5°」の角度が落ちていた／「教えられない」は「教えにくい」 |
| 安いアームを買う前に | 6 | 代理店でも海外版が混ざる但し書きが落ちていた／技適の条件（無線を積んでいる機器）が落ちていた |

**判子「この見立ては、エイイチから」は、作り手本人の言葉（記事の引用の行か見立て帳）にだけ押す、と決め直しました。** Claude の答えの中身はハコブくんの言葉にし、作り手が同意しただけの所は「エイイチも、そうなんだよな、と」の形にします。

- ねらい：画面で、だれの考えかを見る人が取り違えないようにする
- 変わったこと：判子を Claude の言葉に押していた3本（現場で扱えるか・成功の定義・どこまでいじっていい）を直した
- 見込める効果：見込みです。作り手の考えとして見せた所が、記事の中の作り手の発言と合っているかは、公開前の照合で毎回確かめる

突き合わせの指摘の全文は、下の「全文」の節にあります。

### 2本目の台本：作り手の答え3つと、事実の出どころを確かめた

2本目「現場で扱えるか」で作り手に聞いた4問の答えは、次のとおりでした。

| 聞いたこと | 答え | 台本の扱い |
|---|---|---|
| 「店舗のおばちゃんたち」をそのまま使うか | 「店のスタッフさん」に言い換え | 言い換えた |
| 店で配膳ロボットを初めて見たとき | とうとうロボットが店舗に入った！って感激したのを覚えている | やり取り1に入れた。ハコブくんが「同じロボットとして」お礼を言う |
| アパレルの量産のころの、仕様を直した経験 | いらないこれ | 入れない |
| 店とロボットのあいだに立つ役を、どこから始めるか | 大型のお店からスタートしたい | 残った問いに入れた |

最後の問いには、作り手から「なんの間役？」と聞き返されました。台本では、記事の最後で作り手が言った「この辺の問題を解決する力を持つ人」を指していたので、「店とロボットのあいだに立って、止まらない店に切り直す役です」と一言で説明する文を足しました。

事実のうち、アイリスオーヤマの導入実績（7000社以上・2万5000台以上）と、事業の責任者の発言、新しい清掃ロボ JILBY の自動充電と紙パックは、記事の参照先のマイナビニュース（2026年6月29日）を開いて確かめました。発言は「充電が切れたり、紙パックがすぐに一杯になったりという些細なことで、すぐに人の作業に戻ってしまう」「継続的に運用改善に取り組む人材がいない」で、台本では「報道では」と言う形にしました。冒頭の「成功率99%でも1時間に6回」は、記事の中で X の議論の指摘をもとにした例の計算なので、画面に「例の計算」と出しています。

自分の記事が題材の回なので、codex による事実確認はかけていません（作り手の指示）。

### 声：ElevenLabs で86文を作り、「入れないで」を読み直した

台本を `narration.py` に書き写し、点検のスクリプト（`script_check.py`）を通してから、声を作りました。[ElevenLabs](https://elevenlabs.io) は、文章を読み上げる AI 音声のサービスです。声は作り手の Mac の中で作ります。API の鍵は KIOXIA にあり、スクリプトが読むだけです。

| 声 | 文 | 文字数 | かかった時間 |
|---|---|---|---|
| 作り手（Sryf5xKmMsQChU3HsLhZ） | 24 | 約659字 | 38.9秒 |
| ハコブくん（gWJpc8whMBqnF7Y0kc9f・前半） | 31 | 約1,120字 | 記録なし |
| ハコブくん（後半） | 31 | 約1,204字 | 記録なし |
| 直し（42番の文） | 1 | 約29字 | 記録なし |

確認用の動画を見た作り手から、読みの直しが1つありました。

> 4分6秒 入れないが「いれない」が正しい読みです。

「はい。僕も、さっきコケた所は、点数に入れないでほしいです。」を「はいれない」と読んでいたので、読みの直し（ELEVEN_READ）に ('入れないで', 'いれないで') を足し、その1文だけ作り直しました。

字幕が2行に収まらない文が2つあり、字幕の区切り「｜」を足しています（声はそのまま）。

### 脱線の絵：マンガ風の3枚を、4コマの絵柄を参照に付けて作り直した

脱線の場面は4つです。[Gemini の画像の API](https://ai.google.dev/gemini-api/docs/image-generation)（Google の、文章から画像を作る AI。この回は gemini-3.1-flash-image）で、1枚20〜35秒で作りました。

| 場面 | 絵 | 画面に重ねる一言 |
|---|---|---|
| 成功率99%でも1時間に6回 | 止まった配膳ロボットを押して回る店員さん（マンガ風） | 1時間に6回。 |
| 明日の朝、僕にも ChatGPT の瞬間が来る | ロボットが一夜で現れた朝の商店街（写真風） | 一夜で、来ない。 |
| 料理も僕が置きます | 料理を置こうとしてコケるハコブくん（マンガ風） | 最後の動作。 |
| 扉は体当たりで開けます | 調理場の扉の前で、夜から朝まで待つハコブくん（マンガ風） | 開けて……。 |

1回目は、ハコブくんの正面と横の絵だけを参照に付けて作りました。ファミレスの絵には「TABE-BOT」などの文字が入り、朝の街の絵にはのぼりの文字が出たので、文字を描かないよう書き足して作り直しました。そのあと、作り手から次の指示がありました。

> マンガの絵はハコブくんの絵柄をベースに作ってください。

4コマ『ハコブくん』第105話の1ページを「絵柄の参照」として付け、線の太さ・網点・人の顔の描き方をそろえるよう書いて、マンガ風の3枚を作り直しました。ファミレスの配膳ロボットも、ハコブくんと同じ形で描かせています。絵の外枠が出た2枚は、書き出しのときに周りを2%ずつ切り落としました。

【画像】LOG429_02_manga_style_before_after.jpg 脱線のマンガの絵の比べ。左が1回目（コケるハコブくん・扉の前のハコブくん）、右が4コマ第105話を絵柄の参照に付けて作り直した絵

【画像】LOG429_06_fall.png 料理を置こうとしたハコブくんが全身で前のめりにコケた場面。紙には「料理をテーブルに置く お客さん」「トレーに載せる 店員さん」、右下で作り手が驚いている

- ねらい：脱線のマンガの絵を、サイトの4コマと同じキャラクター・同じ絵柄に見せる
- 変わったこと：Gemini に渡す参照の絵に、4コマの1ページを足した
- 見込める効果：見込みです。4コマを読んだことがある人には、同じ世界の話だと分かる

### ボタンの天丼：固まったハコブくんを「再開」で戻す

紙の外、ハコブくんの頭の上に「再開」のボタンを出しました。HTML のボタンが出て、押されると沈んで朱に変わり、「ピッ」の文字と音が出ます。1回目と2回目は作り手が押し（字幕の上に「エイイチが押す」）、最後の問い「あなたの店でロボットが止まったら、誰が戻しますか。」のあとだけ、ハコブくんが自分で押して「自分で戻りました。」と言います。

【画像】LOG429_03_restart_button.png 持ち込みの場面。ハコブくんの頭の上に「エイイチが押す」の札と「再開」のボタン。紙には「ChatGPT の瞬間は来る？」と、ChatGPT とロボットの2つのカード

### 書き出し v1・v2：読みの直しと、弾むときの下の隙間

1本目の部品（kabe_kit.py）を写し、場面（scenes_kabe.py）を書き替えて、作業環境で書き出しました。紙を1コマずつ撮るので、8分35秒で約27分かかります。

確認用の v1 を見た作り手から、読みのほかにもう1つ指摘がありました。

> 俺が上下に動くとき下にほんの少し隙間ができるので修正してください。

作り手のドット絵は、声に合わせて4ピクセル（1ドット）上に弾みます。絵の下の端が画面の下の端にちょうど合っていたので、弾んだ分だけ隙間が見えていました。絵の一番下の行を3ドットぶん下へ伸ばし、弾んでも画面の下まで絵が届くようにしました（差分は「全文」の節）。v2 で、作り手が話している5コマの画面の一番下の行が、上着の色（63,63,71）か輪郭の黒になっていることを確かめています。

紙のカードで、1〜2文字だけ次の行に落ちる所（「鍵」「く」「高」など）もありました。`inkl()` という関数を足し、文の中の「／」の所で行を分けるようにしました。

### 書き出し v3：場面ごとに大きな動きを1つ置いた

v2 で問題ないとされたあと、作り手が動画を見直して、冒頭の「全体に動きがないね」の指摘がありました。

最初に、Claude が1本目の完成した動画を見ずに、iCloud にあった1本目の場面のファイルを写して作っていたことを作り手に伝えました。そのうえで、1本目の完成版と2本目を、1秒に10コマずつ縮小した画面の差で比べました。前のコマから画面が平均0.5以上変わったコマを「動いている」、画面の右の余白と上の端の色のばらつきが大きいコマを「写真や映像が出ている」と数えています。

| 動画 | 長さ | 動いている時間 | 大きく動いている時間 | 写真や映像が出ている時間 |
|---|---|---|---|---|
| 1本目（頭脳は脳のように分かれる） | 425秒 | 16% | 7% | 23% |
| 2本目 v1 | 515秒 | 12% | 6% | 18% |
| 2本目 v3 | 515秒 | 13% | 6% | 20% |

30秒ごとの「動いている時間」は次のとおりです。

| 区間 | 0 | 30 | 60 | 90 | 120 | 150 | 180 | 210 | 240 | 270 | 300 | 330 | 360 | 390 | 420 | 450 | 480 | 510 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1本目 | 8 | 29 | 10 | 22 | 37 | 12 | 9 | 19 | 7 | 13 | 13 | 13 | 7 | 21 | 6 | — | — | — |
| 2本目 v1 | 14 | 33 | 10 | 8 | 9 | 16 | 8 | 6 | 9 | 9 | 6 | 18 | 17 | 6 | 9 | 4 | 23 | 8 |
| 2本目 v3 | 18 | 33 | 11 | 11 | 10 | 16 | 7 | 6 | 9 | 9 | 6 | 18 | 17 | 6 | 9 | 4 | 24 | 8 |

1本目も、背景は黒一色で、写真が出るのは脱線の場面と自己紹介の映像だけでした。作り手の「背景画像も入れてない」に合わせて背景を足すかを聞くと、作り手は「頭脳は脳のように分かれるの形に合わせて。内容確認してください」と答えました。1本目との違いは場面の作り方だったので、場面ごとに主役になる動きを1つずつ足しました。

| 場面 | v3 で足した動き |
|---|---|
| つかみ | 「99%」を0から数え上げる。「6回」を大きく落とす。作り手の「それ、優秀なのかな」に朱の判子「優秀？」 |
| 持ち込み | 「ChatGPT の瞬間」を大きく出し、ChatGPT とロボットを大きな2枚のカードで並べる |
| どんな仕事から | 「失敗が許せる」「繰り返しが多い」を大きなカードで出す |
| 初めて見たとき | 作り手の言葉に判子「感激」 |
| 使い方 | テーブル番号のボタン1〜4を並べ、3番が押されて「ピッ」。そのあと「ほぼ不要」を大きく落とす |
| 足りなくなる人 | 「安く↓」を大きく落とす |
| 扉を通らない手 | 調理場｜棚｜ロボットの帯が順に伸びる図 |
| 残った問い | 「まだない」を大きく落とす |

【画像】LOG429_04_table_buttons.png 使い方の場面。紙に「使い方は、テーブル番号のボタンを押すだけ」とボタン1〜4。3番が朱に沈み「ピッ」の文字

- ねらい：場面ごとに、目が止まる動きを1つ置く
- 変わったこと：動いている時間が12%から13%に、写真や映像が出ている時間が18%から20%になった
- 見込める効果：1本目の16%には届いていない。3分〜5分半（暗転して縦書きを出す場面と、3つの問いの場面）は、まだ1本目より落ち着いて見える。公開後、YouTube の視聴者維持率でこの区間に落ち込みがあるかを確かめる

【画像】LOG429_08_scene_sheet_v3.jpg v3 の場面の一覧（37コマ）。場面ごとに静止画が並ぶ

### サムネイル・タイトル・概要欄

サムネイルの背景は Gemini で作りました（ファミレスで、止まった配膳ロボットの画面に店員さんが指を伸ばす写真風の絵）。2枚作った背景のうち1枚は、奥ののれんと機体に文字が出たので使っていません。文字は動画と同じ部品（thumbnail.py）で重ねました。

| 案 | 上の小さな一言 | 大きな文字 | ハコブくんの札 |
|---|---|---|---|
| A（決めた案） | ロボットが店に広がる条件 | 賢さ、じゃなかった | 止まったら、誰が戻す？ |
| B | 配膳ロボット | 成功率99%でも 10分に1回 呼ばれる | 優秀……ですか？ |

タイトルは、作り手が3案から「配膳ロボットが店に広がった理由は「賢さ」じゃなかった」を選びました。概要欄は目次10個・出どころ・生成 AI で作った絵の断り・相談の連絡先を入れて1,951字です。

【画像】LOG429_07_thumbnail_ab.jpg サムネイルの A 案（左・賢さ、じゃなかった）と B 案（右・成功率99%でも10分に1回呼ばれる）。どちらもファミレスで店員が配膳ロボットの画面に指を伸ばす背景に、左下のハコブくん

### 縦長ショート3本：脱線のマンガの絵の前で、大きなハコブくんを動かした

本編をアップロードしたあと、縦長ショートを3本作りました。部品は1本目の考察回のショート（kabe_short.py の版2）を写し、3本の中身だけを書き替えています。最初の数秒は、本編の脱線のマンガの絵を画面いっぱいに出し、大きなハコブくん（高さ900ピクセル）が動きます。本題に入ると絵が暗くなって紙が出て、ハコブくんは左下の全身に戻ります。声は本編の声をそのまま使いました。

| ショート | 長さ | 使った本編の文 | 始まりの絵 | 大きなハコブくんの動き |
|---|---|---|---|---|
| ショート1_成功率99パーセント | 23.5秒 | 0〜4（つかみ） | 止まった配膳ロボットを押して回る店員さん | 画面の左右の端まで、0.5秒ごとに行き来する |
| ショート2_料理も僕が置きます | 23.0秒 | 27・28・25・26・29（順番を入れ替えた） | 料理を置こうとしてコケるハコブくん | 跳ねたあと前のめりにコケて、次の文が終わるまで倒れたまま |
| ショート3_扉は体当たり | 22.1秒 | 63・64・66 | 扉の前で朝まで待つハコブくん | 左の端の壁に約1秒ごとにぶつかり「ゴン」。ぶつかる間は壁の方を向く |

ショート2の最後の文は頭の「……はい。」を、ショート3の3つ目の文は頭の「なので、」を切って始めています。切る位置は、声の波形を20ミリ秒ずつ見て、言葉の後ろの無音の真ん中にしました（0.95秒と0.66秒）。字幕は1行11字に収まらない文があったので、区切りの「｜」を足しています。

版1は、1本目と同じ動き（下から飛び出す・跳ねる）で作りました。白いマンガの絵の上では、白い見出しと「絵は生成AI（Gemini）で作成」の注記が読みにくかったので、画面の上560ピクセルを上から下へ薄くなる黒で暗くしました。ショート2の「ドテッ」は大きなハコブくんの後ろに隠れていたので、上に移しています。

版1を見た作り手から、3本とも動きの直しがありました。

> 1は左右に何度も素早く動いている描写に修正2はハコブくん転けないと。修正
> 3の動きがほぼないので、壁（左の端）に何度もぶつかってるような動きにしてください。

大きなハコブくんの動きに、dash（左右に走る）・fall（コケる）・wall（壁にぶつかる）の3つを足しました。

- dash：最初は動く幅を、ハコブくんが画面に収まる範囲（約240ピクセル）にしていて、動いて見えませんでした。左右の端から少しはみ出すまで走るようにし、往復を0.62秒から0.5秒に縮めました。向きを変える所で体が傾き、走る音が鳴ります
- fall：本編でコケる動きと同じく、前の足もとを中心に約86度まで倒します。最初は約0.8秒で起き上がっていたので、「だから人に任せたんだよ」が終わるまで倒れたままにしました。大きなハコブくんは、倒れても画面に収まるよう高さを720ピクセルにしています
- wall：0.5秒かけて出てきたあと、0.95秒ごとに、壁へ向かって速くなりながら左の端にぶつかり、反って跳ね返ります。ぶつかる時刻を計算し、「ゴン」の文字と音をその時刻に置きました

版2を見た作り手から、もう1つ指摘がありました。

> 3はハコブくんの向きが逆ね。
> 小さくなる時はエイイチに向き合う向きに戻る

ハコブくんの絵は右向き（作り手の方を向く）です。壁にぶつかっている間だけ絵を左右反転させ、体の傾きも逆にしました。小さくなって左下に戻る所で、右向きに戻ります。

【画像】LOG429_09_shorts.jpg 縦長ショート3本の場面。左から、ショート1で左右に走るハコブくん（2枚）、ショート2でコケる所と倒れたまま紙が出る所、ショート3で壁に「ゴン」とぶつかる所（壁の方を向いている）と、小さくなって作り手の方へ向き直った所

- ねらい：ショートの最初の数秒で、スワイプされずに目を止めてもらう
- 変わったこと：大きなハコブくんの動きを、回ごとに5つ（飛び出す・跳ねる・走る・コケる・壁にぶつかる）から選べるようにした
- 見込める効果：見込みです。YouTube のアナリティクスで、ショートの「スワイプされずに見られた割合」を1本目のショートと比べる

### アップロード用の動画を Mac に送るとき、出力フォルダが中身を書き換えていた

作業環境から Mac へ送れるのは、1ファイル約20MB までです。本編の mp4（約53MB）を18MBずつに分けて送り、Mac でつなぐと、指紋（md5）が手元と合いませんでした。調べると、作業環境の出力フォルダ（`/mnt/user-data/outputs/`）に置いた mp4 は、置いたあとに中身が少し書き換わっていました（53,377,948 バイトが 53,383,823 バイトに）。書き換わった mp4 も最後まで再生できることを ffmpeg で確かめています。

v3 からは、mp4 を gzip にしてから18MBずつ分けて送り、Mac で gzip を開いて指紋を確かめてから、アップロード用のフォルダに書きました。手元の mp4 と同じ指紋（4b315271269d38284d56241bcf8381f5・53,579,168 バイト）になっています。

### 保存した場所

| もの | 場所 |
|---|---|
| 6本の台本のたたき | iCloud `動画/{動画名}/考察回_台本たたき.md` |
| 2本目の作り方のファイル（narration.py・scenes_kabe.py・kabe_kit.py・sound.py・thumb_A.py・thumb_B.py・概要欄_下書き.md・背景/・サムネ素材/） | iCloud `動画/現場で扱えるか/` |
| 確認用の動画 v1・v2・v3 | KIOXIA `r2r2r-data/videos/現場で扱えるか/` |
| 縦長ショート3本（ショート1・2は版2、ショート3は版3）とタイトル・説明文 | KIOXIA `r2r2r-data/videos/現場で扱えるか/ショート/`（前の版は `_旧版_版1/`・`_旧版_版2/`） |
| ショートの部品 | iCloud `動画/現場で扱えるか/kabe_short.py` |
| YouTube に上げる一式（動画・サムネイル・タイトル・概要欄・投稿文） | KIOXIA `r2r2r-data/videos/現場で扱えるか/アップロード用/` |
| 作り手に聞いた答え | iCloud `動画/_制作ベース/エイイチの見立て帳.md` |
| 考察回の決まりの書き足し | iCloud `動画/_制作ベース/video_rules.md` の10節 |


## 作業ログ ― この回で使った台本・コード・プロンプト・出力（全文）

ここから下は、この回の台本のたたき・照合の指摘・コード・プロンプト・出力の全文です。台本のたたきは、照合で直したあとの版です（照合の指摘の行番号は、直す前の版の行番号）。

### 台本のたたき：現場で扱えるか（LOG389 がもと・考察回_台本たたき.md）

```markdown
# 考察回「現場で扱えるか」― 台本のたたき（LOG389）

> 【相づち】は、2026-11-02 にエイイチが「採っていい」と了承済み（6本とも）。

共通の決まりは _ネタ帳/考察回_壁打ちの型/考察回_壁打ちの型_台本たたき.md と video_rules.md 10節

もとの記事: LOG389「ロボットを広げるのは、性能より現場で扱えるかだった」
https://pixelstomotors.com/record/service-robot-last-mile
尺の目安: 約8分　／　柱: ① 入れたらどうなる（配膳ロボットのシリーズ「何台入れたら店は変わる」へつなぐ）

## この回の問い

紙に書く縦書きの一文:

> ロボットが店に広がるかを決めるのは、賢さか。

答え（まとめで紙に書く一文）:

> 決めていたのは、店の人が自分で扱えるように、作業と店の作りを切り直せるか。

## 天丼（くり返しの笑い）

1本目の「考え中の秒数」は使わない。この回は「ボタン」でくり返す。

- ハコブくんが話の途中で固まると、頭の上にテーブル番号のボタン（配膳ロボットの画面と同じ形）が出る。エイイチが押すと「ピッ」と鳴って再開する
- 冒頭・やり取り2・最後の3回。最後だけ、ハコブくんが固まって、自分でボタンを押して戻る（「誰でも戻せる」のオチ）

## 脱線の場面の候補（4つ）

| 場面 | 画面いっぱいに出すもの（Gemini で作る絵） | ひと言 |
|---|---|---|
| 「明日の朝、僕にも ChatGPT の瞬間が来ます」 | 写真風：朝日の差す街に、人型ロボットが一斉に現れて、通りの人が全員スマホで撮っている。一夜で世界が変わった朝の妄想 | 一夜で、来ない。 |
| 成功率99%でも1時間に6回 | マンガ風（4コマと同じ白黒）：ファミレスの店内で、店員さんが汗をかいて走り回り、あちこちで止まった配膳ロボットを押している | 1時間に6回。 |
| 「料理も僕が置きます」→ コケる | マンガ風：ハコブくんがテーブルの前で前のめりになり、料理の皿が宙を舞っている瞬間（ハコブくんの三面図を参照に付ける。左下のハコブくんは消す） | 最後の動作。 |
| 扉の前で待つハコブくん | マンガ風：調理場の扉の前で、トレーを載せたハコブくんがじっと待っている。窓の外は夜から朝に変わっている（同じ構図を2コマ並べたような1枚） | 開けて……。 |

- 絵に文字を描かせない。ひと言は動画の側で重ねる
- 4つ目の扉は、病院で物を運ぶハコブくんの設定とつながる。マンガの中の話として見せる

## 表情の割り当て（主な場面だけ）

| 場面 | ハコブくん | エイイチ |
|---|---|---|
| つかみ「1時間に6回」 | 驚き | 腕組み |
| 「明日の朝、僕にも来ます」→ ボツ | ＞▽＜ → 困り眉 | 半目でツッコむ |
| ボタンで固まる → 押されて再開 | 点の目 → 小さな笑み | 指さす（押す） |
| 「店のスタッフさんでも使えてる」 | 驚き → ＞▽＜ | うなずく |
| 「料理も僕が置きます」→ コケる | ＞▽＜ → ×の目 → 困り眉 | 吹き出して笑う |
| 3つの問い（理由・戻し方・読める動き） | 目を閉じる → 基本 | ひらめく |
| アイリスオーヤマの紙パック | 驚き・全身で飛び出す | のけぞって驚く |
| 「扉は体当たりで」→ ボツ | ジト目 → 困り眉 | 首をかしげる |
| 最後に自分でボタンを押す | ＞▽＜ | うなずく |

## 台本

### 0 つかみ（0:00〜0:35）

ハコブくん：成功率、99%。ロボットとしては、かなり優秀です。
ハコブくん：でも、1時間に600回働くと、1時間に6回、人が駆けつけることになります。
（紙に「99%」が置かれ、横に「1時間に6回」が数え上がる。出どころの札「記事の中の例の計算」）
ハコブくん：店の人からすると、10分に1回、呼ばれるロボットです。
エイイチ【相づち】：それ、優秀なのかな。
ハコブくん：……僕も、自信がなくなってきました。
（紙に問いの縦書き「ロボットが店に広がるかを決めるのは、賢さか。」）
ハコブくん：今日は、答えを伝える回ではありません。エイイチが考えている途中を、そのまま見せます。

### 1 持ち込み（0:35〜1:40）

ハコブくん：（自己紹介の定型文）
ハコブくん：エイイチが持ち込んだのは、海外のロボットや AI の人たちの、X の議論でした。
ハコブくん：お題は、「ロボットにも、ChatGPT のように、一夜で世の中が変わる瞬間は来るのか」。
エイイチ【本人】：実際どうなんだろうね。（1番目の見出し）
ハコブくん（ボケ）：来ます。明日の朝、僕にも来ます。起きたら、なんでもできるようになっています。
（脱線①：一夜で世界が変わる朝の街 →「一夜で、来ない。」→ 紙が戻る。ボードのボケに「ボツ」の判子）
ハコブくん：議論には、「できるようになる瞬間は来ても、広がるには時間がかかる」という声がありました。
ハコブくん：ChatGPT は、ブラウザを開けば試せました。間違った答えが出ても、読み流せば済みます。
ハコブくん：ロボットは、置く場所を空けて、止まったときの対処を決めて、店のやり方を変えないと使えません。
（ハコブくんが固まる。頭の上にボタン。エイイチが押す。「ピッ」）
ハコブくん：……失礼しました。今のが、止まったときの対処です。

### 2 やり取り1：なぜ配膳ロボットだけ先に広がったか（1:40〜3:00）

ハコブくん：では、どんな仕事から広がるのか。失敗が許せて、繰り返しの多い作業から、だと考えました。
エイイチ【本人】：そうだね。データも取りやすいし、入れるハードルも低いし、お金もかからないからね。（2番目の見出し）
エイイチ【本人】：サービスロボットが広がり始めたのも、このあたりが関係してるね。（3番目の見出し）
ハコブくん：ファミレスの配膳ロボットは、その条件が全部そろっていました。
エイイチ【本人・聞き取り】：初めて店で見たときは、とうとうロボットが店舗に入った！って感激したのを覚えてる。（2026-11-02 本人に聞いた答え）
ハコブくん：……感激していただいて、ありがとうございます。同じロボットとして。
（紙に3つの面が置かれる:「止まっても、料理が少し遅れるだけ」「毎日、何百回も往復」「人が集まらない」）
ハコブくん（へー）：しかも、一番難しい所を、ロボットにやらせていません。料理をテーブルに置くのはお客さん。トレーに載せるのは店員さんです。
ハコブくん（ボケ）：では僕が、料理もテーブルに置きます。最後まで、責任を持って。
（ハコブくんが前のめりにコケる。「ドテッ」→ 脱線③：皿が宙を舞う →「最後の動作。」→ 紙が戻る。ボケに「ボツ」）
エイイチ【相づち】：だから人に任せたんだよ。
ハコブくん：……はい。配膳ロボットは、頑張らない所を決めて、広がりました。

### 3 山場：扱えるか（3:00〜4:40）

ハコブくん：もう1つ、配膳ロボットには強みがあります。使い方が、テーブル番号のボタンを押すだけ。止まったら、どかせばいい。
エイイチ【本人】：店のスタッフさんでも使えてるしね。ポイント高いよね。（4番目の見出し。「店舗のおばちゃんたち」を本人の指示で言い換え）
ハコブくん：研修もマニュアルも、ほとんどいりません。入れたあとに、エンジニアを呼ぶ手間が、ほぼ消えました。
ハコブくん：裏を返すと、どんなに賢いロボットでも、止まったときにどうすればいいか分からなければ、広がりません。
エイイチ【本人】：そうなんだよな。そこをしっかり見極めないと、どんなに素晴らしい技術のロボットでも、広がらないよね。（5番目の見出し）
（暗転。縦書きで一文「止まったとき、店の人が戻せるか。」を、ハコブくんの言葉として薄い灰の面に書く。判子は押さない。下に小さく「エイイチも、そうなんだよな、と」。エイイチはうなずく絵）
ハコブくん：見極めは、3つの問いに分けられます。
（紙に3つの面が1つずつ置かれる）
ハコブくん：1つ目。止まったとき、理由が分かるか。「通れません」なのか、「物を見失いました」なのか。
ハコブくん：2つ目。エンジニアを呼ばずに、その場の人が戻せるか。
ハコブくん：3つ目。次にどう動くか、周りの人に読めるか。読めないと、怖いです。
ハコブくん（へー）：この3つは、技術のデモでは、ほとんど評価されません。
エイイチ【相づち】：デモの点数には、入らないんだね。
ハコブくん：はい。僕も、さっきコケた所は、点数に入れないでほしいです。
エイイチ【相づち】：入れとくよ。

### 4 やり取り2：足りなくなるのは誰か（4:40〜6:00）

ハコブくん：話を、店の外に広げます。配膳や清掃のように、動き回る仕事のロボットは、機体が安くなってきました。
エイイチ【本人】：移動系はほんとうに早そうだし、コストも一気に安くなりそうだよね。その分、入れるための営業やエンジニアが足りなくなりそうだよね。（7番目の見出し）
【見立て帳】エイイチ：ロボットで利益が残るのは、作る側より、入れて回す側だと思う。（physical-ai.md・2026-10-29）
ハコブくん：足りなくなるのは、店の通路の幅や段差を見て、どこまでをロボットに任せるか線を引き、止まったときの対処を店のルールにする人です。
（ハコブくんが固まる。ボタン。エイイチが押す。「ピッ」）
ハコブくん：……ありがとうございます。今みたいに戻してくれる人が、足りないんです。
エイイチ【本人】：でも、サービスロボットを入れるのは地方の方が切実なんだよね。この問題をどう解決できるかが鍵だね。（8番目の見出し）
エイイチ【本人】：家電量販店とか電気屋さんが、候補には上がりそうだけど、実際どうなんだろう？（9番目の見出し）
ハコブくん（へー）：町の電気屋さんは、何かあれば、すぐ来てくれる関係を、もう持っています。止まったときの駆けつけに向いています。
ハコブくん：ただ、どこまでロボットに任せるかを店と一緒に決める力は、どちらにもまだありません。そこは、離れた所から専門の人が受け持つ形が、現実的だと考えました。
エイイチ【相づち】：役割を分けるんだね。

### 5 やり取り3：止まらない作りと、扉（6:00〜7:20）

エイイチ【本人】：アイリスオーヤマが、ロボットを扱ってなかったっけ？ どうしてるか調べてみて。（10番目の見出し）
ハコブくん：調べました。これまでに、7000社以上に、2万5000台以上を入れているそうです。
ハコブくん：事業の責任者は、充電切れや、紙パックが満杯になるような小さなことで、すぐ人の手の作業に戻ってしまう、と話しています。
ハコブくん：そして、現場で運用を直し続ける担い手がいないことが、広める上での壁だ、と。
ハコブくん（へー）：なので、新しい清掃ロボは、掃除が終わると自分で充電に戻り、紙パックは家電と同じように替えやすくしました。
（ハコブくんが驚いて全身で飛び出す）
ハコブくん：……紙パックです。担い手がいないなら、紙パックで人を呼ばない作りにする。
エイイチ【相づち】：家電の会社らしいね。
ハコブくん：残る壁は、下げ膳です。食べ終わったお皿を、洗い場まで運ぶ仕事です。
エイイチ【本人】：ロボットがお店のフロントからバックヤードに行くには、扉を開けられないといけない。ここが今、目に見える問題かな。（15番目の見出し）
（脱線④：扉の前で朝まで待つハコブくん →「開けて……。」→ 紙が戻る）
ハコブくん（ボケ）：大丈夫です。扉は、体当たりで開けます。
（ボケに「ボツ」）
ハコブくん（へー）：決まりで求められているのは、調理場を客席と仕切ることです。どう仕切るかは、地域の決まりや保健所の判断で変わります。
ハコブくん：なので、扉を通らない手があります。両側から取り出せる棚を客席側に置いて、ロボットはそこにトレーを置くだけにする。
エイイチ【本人】：そうだね、現場設計だね。正直、直接洗い場までロボットが持って行けたら最高だけどね。（16番目の見出し）
ハコブくん：それは、新しい店や改装のときに、ロボットの通り道ごと設計する所から、だと考えました。

### 6 まとめ（7:20〜7:50）

（ボードが1枚の表になる。ボツの判子が押された3つ:「明日の朝、僕にも来る」「料理も僕が置く」「扉は体当たり」）
ハコブくん：残っている壁の多くは、ロボットの賢さではありませんでした。店の作りと、仕事の分け方と、保健所との調整です。
（紙にまとめの一文「決めていたのは、店の人が自分で扱えるように、作業と店の作りを切り直せるか。」）
ハコブくん：ちなみに、ボツになった3つは、全部、僕が自分でやろうとしたことです。
エイイチ【相づち】：全部やらなくていいんだよ。

### 7 残った問い（7:50〜8:20）

エイイチ【本人】：この辺の問題を解決する力を持つ人が、フィジカルAIの時代には重宝されそうだね。（18番目の見出し）
ハコブくん：店とロボットのあいだに立って、止まらない店に切り直す役です。ただ、その役には、まだ名前も、求人の枠もありません。
ハコブくん：エイイチなら、どんな店から始めますか。
エイイチ【本人・聞き取り】：大型のお店からスタートしたいね。（2026-11-02 本人に聞いた答え）
ハコブくん：誰が最初にやるのかは、まだ分かりません。
ハコブくん：この考察ノートの全文は、サイトの記事にあります。調べた決まりの出どころも、そちらに。
ハコブくん：あなたの店でロボットが止まったら、誰が戻しますか。
（ハコブくんが固まる。頭の上にボタン。エイイチが手を伸ばす前に、ハコブくんが自分で押す。「ピッ」）
ハコブくん：自分で戻りました。
エイイチ【相づち】：それが一番えらい。

## 裏を取る所（台本を固める前に）

- 「成功率99%・1時間に600回 → 1時間に6回」は、記事の中で Claude が置いた例の計算。実在の機体の数字ではないので、画面の札で「例の計算」と出す。「10分に1回」は 60÷6 の言い換え
- アイリスオーヤマの「7000社以上・2万5000台以上」は、記事では「だそうです」としか書いていない。記事の参照情報で出どころ（会社の発表か報道か）を確かめ、言い方を決める。動画にする時点の最新の数にそろえる
- 事業の責任者（記事では事業本部長）の発言は、出どころの原文で言い方を確かめる。担い手の話が本題で、充電切れ・紙パックはその例
- 新しい清掃ロボ（JILBY・2026年7月）の自動で充電に戻る機能・紙パックを、製品のページで確かめる
- 食品衛生法の施設基準の「区画」の書き方と、自治体で変わること（記事では那覇市の基準を例にした）を、原文で確かめる。エイイチの【本人】「開けっぱなしは法律的にはNG」は、記事で Claude が整理し直した所なので、台本では使っていない（本人の言葉は「扉を開けられないといけない」までにした）
- X の投稿は画面写真を出さない（記事と同じく、中身を文で紹介する）。投稿者の名前を出すかは、概要欄だけにするか決める
- 「何百回も往復」「町の電気屋さんの向き不向き」は、記事の中の Claude の見立て。事実のように言い切っていないか、照合のときに見る

## エイイチに聞きたいこと（4問）

（2026-11-02 に答えをもらい、台本に入れた）
1. 「店舗のおばちゃんたち」→「店のスタッフさん」に言い換え（3 山場）
2. 店で初めて見たとき →「とうとうロボットが店舗に入った！って感激したのを覚えている」（2 やり取り1 に入れた）
3. アパレルの量産の経験 → 要らない（入れない）
4. 間をつなぐ役を始める店 →「大型のお店からスタートしたい」（7 残った問いに入れた）

## 記事との突き合わせで直した所

- 1 持ち込み: 「議論で多かった」→「という声がありました」（紹介したのは3人のうち2人で、多かったとは言えない）
- 2 やり取り1: 【本人】の前半「失敗が許せて、繰り返しの多い作業から」は Claude の文の引用だったので、ハコブくんの言葉に移した。本人の言葉は「そうだね。データも取りやすいし…」から
- 3 山場: 判子「この見立ては、エイイチから」を外した。3つの問いと「性能より扱えるUX」は Claude の答えなので、ハコブくんの言葉（薄い灰の面）にし、「エイイチも、そうなんだよな、と」を添えた
- 3 山場: 「デモの映像は、うまくいった回だから」は記事にない理由だったので、記事の「技術デモでは、ほぼ評価されません」に戻した。続く相づちとボケも、理由を足さない形に直した
- 5 やり取り3: 「会社の発表では」を外し、記事の「だそうです」の言い方にした。出どころは裏を取る所で確かめる
- 5 やり取り3: 事業本部長が言った壁は「現場に運用改善を続ける担い手がいないこと」。充電切れ・紙パックは人の作業に戻る例として言い、「壁は紙パック」と言わない形にした
- 5 やり取り3: 「新しい店を建てるとき」に、記事にある「改装のとき」を戻した
- 問い・6 まとめ: まとめの一文を記事の結論に戻した（「店の人が自分で扱えるように、作業と店の作りを切り直せるか」）
```

### 台本のたたき：照明で崩れるピッキング（LOG412 がもと・考察回_台本たたき.md）

```markdown
# 考察回「壁打ちの型」― 台本のたたき（LOG412）

> 【相づち】は、2026-11-02 にエイイチが「採っていい」と了承済み（6本とも）。

共通の決まりは _ネタ帳/考察回_壁打ちの型/考察回_壁打ちの型_台本たたき.md と video_rules.md 10節。

もとの記事: LOG412「ロボットのピッキングは照明で崩れる ― 次のアームは人の雑さをまねる」
https://pixelstomotors.com/record/lighting-breaks-picking
尺の目安: 約8分　／　柱: ②時事を入り口に（X の投稿：ある会社の発表でピッキングが崩れた話）。後半は③自分で試してみた（mechArm 270 と π0.5 の実感）に寄る

- エイイチのセリフの印: 【本人】＝ LOG412 の対話にある本人の発言を話し言葉に整えたもの（行末の（対話N）は、記事の作業ログの何往復目か。全14往復）。【相づち】＝ Claude の案。本人が採るか選ぶ（使わないなら消す）
- 机の上の話は「エイイチの機体とソフトの組み合わせでは」と範囲を付ける。受け渡し動作は入れない
- 投稿した人・発表した会社の名前は出さない（記事でも「投稿した人」に置き換えている）

## この回の問い（紙に縦書き）

照明が変わると、ロボットはなぜ掴めないのか。

（記事の問いの文と同じ。答えは山場のあとで「ずれても、見ながら直せるか」に着く）

## 天丼（この回のくり返しの笑い）

1本目の「考え中の秒数」の代わりに、**照明が変わるとハコブくんがエイイチを見分けられなくなる**をくり返す。

- 画面の照明が切り替わる（暗くなる・夕焼け色になる）たびに、ハコブくんがエイイチに「……どちら様ですか」
- 1回目＝つかみの直後、2回目＝やり取り1の途中、3回目＝最後。最後だけ、照明が変わってもハコブくんが首を振って見直し「エイイチですね。見ながら直しました」で締める
- 照明の切り替えは、紙と背景の色だけを変える（キャラの絵は変えない）。1回0.5秒ほど

## 脱線の場面の候補（4つ）

| 場面 | 画面いっぱいに出すもの（Gemini で作る絵） | ひと言 |
|---|---|---|
| 「物そのものではなく、その部屋での見え方を覚えている」 | 写真風：同じ机・同じ赤いブロックを、昼の窓の光・夕焼け・青白い蛍光灯で撮った3枚を横に並べた1枚。ブロックの色の見え方だけがはっきり違う | 全部、同じブロックです。 |
| 「最速は、全部の照明で練習することです」（ボツ） | マンガ風（4コマと同じ白黒）：ミラーボールが回るディスコの床で、小さなロボットアームが必死にブロックを探している。横でハコブくんがサイリウムを振っている | 全照明対応。 |
| 「人に手首カメラはない」 | 写真風：オフィスで真顔の会社員が、手首に小さな監視カメラを巻いてコーヒーカップを持っている。周りの同僚は気にしていない | 人には、要りません。 |
| 「落としたら拾う。人はこれを失敗と数えていない」 | マンガ風：床一面に転がった何百個ものブロックの真ん中で、ハコブくんが1つずつ指さして数えている | 全部、数えています。 |

- ハコブくんが出る絵は、4コマのキャラの三面図（hakobu_front.png・hakobu_side.png）を参照画像に付ける。絵にハコブくんがいる場面は、左下のハコブくんを消す
- 絵に文字を描かせない。ひと言は動画の側で重ねる

## 表情の割り当て（主な場面）

| 場面 | ハコブくん | エイイチ |
|---|---|---|
| つかみ「作った人たちの説明は、電気のせい」 | 驚き | 腕組み |
| 照明が変わって「……どちら様ですか」（1・2回目） | 点の目 → 困り眉 | 半目でツッコむ |
| 「作った人の腕の問題ですね」→ ボツ | ＞▽＜ → 困り眉 | のけぞって驚く → 半目でツッコむ |
| ディスコの脱線のあと | 小さな笑み | 吹き出して笑う |
| 「目標、1億回です」→ ボツ | ＞▽＜ → 困り眉 | 首をかしげる |
| 「上カメラだけで、よく掴める」 | 驚き | ひらめく |
| 頭を左右に振る実演（頭を動かして奥行きを知る） | 基本 → 小さな笑み（全身の絵で、体ごと左右に揺らす） | うなずく |
| 「少しだけ補正します」（手首カメラが補っているのは目の側） | ジト目 → 小さな笑み | 首をかしげる |
| 「僕は全部数えています」 | ＞▽＜ | 吹き出して笑う |
| 「ヒューマノイドだけがフィジカルAIではない」→ 驚いて飛び出す | 驚き・全身で飛び出す → ＞▽＜ | 指さす |
| 最後「見ながら直しました」 | ウインク | うなずく |

体の動きは2回まで（頭を振る実演・飛び出す）。

## 台本

### 0 つかみ（0:00〜0:30）

ハコブくん：ロボットが、急に物を掴めなくなりました。作った人たちの説明は、電気のせい。
ハコブくん：停電ではありません。部屋が変わって、照明の条件が変わったから、だそうです。
エイイチ【本人】：まぁ、そんなもんだよ。（対話1）
ハコブくん：そんなもん、なんですか。
（画面の照明が夕焼け色に切り替わる）
ハコブくん：……どちら様ですか。
エイイチ【相づち】：さっきまで話してたよね。
ハコブくん：失礼しました。照明が変わったので、別の人かと。
（紙に問いの縦書き「照明が変わると、ロボットはなぜ掴めないのか。」）
ハコブくん：今日は、答えを伝える回ではありません。エイイチが考えている途中を、そのまま見せます。

### 1 持ち込み（0:30〜1:30）

ハコブくん：（自己紹介の定型文）
ハコブくん：きっかけは、X の1本の投稿でした。
ハコブくん：ある会社の、フィジカルAIの発表で、ロボットのピッキング、つまり物を掴んで取り出す作業が、ほとんど成功しなかった。発表した人たちの説明は、「部屋が変わって、照明の条件が変わったから」。
ハコブくん：投稿の問いは、それはフィジカルAIの限界なのか、作った人の腕の問題なのか、でした。
ハコブくん（ボケ）：分かりました。作った人の腕の問題ですね。
エイイチ【相づち】：それ言っちゃう？
ハコブくん：……ボツですか。（ボツの判子）
ハコブくん（へー）：少ないお手本で学んだロボットは、物そのものではなく、「その部屋での物の見え方」まで覚えています。影や反射が変わるだけで、ロボットには別の部屋に見えます。
（脱線：同じブロックを3つの照明で撮った写真「全部、同じブロックです。」）
ハコブくん：なので問題は、腕の良し悪しより、どの条件なら動いてよいかを決めないまま、会場を変えたことでした。

### 2 やり取り1：最速の進め方（1:30〜3:00）

ハコブくん：では、照明が変わっても掴めるようにするには、どうすればいいのか。
エイイチ【本人】：これ実際のところ、どういう進め方が最速なのかね。環境の条件を学ばせるのか、環境のほうを合わせるのか。（対話2）
エイイチ【本人】：外でロボットを動かす案件は絶対にあるから、照明だけに頼るのも問題なんだよ。（対話2）
ハコブくん（ボケ）：最速は、全部の照明で練習することです。昼、夜、夕焼け、それからディスコ。
（脱線：ディスコのマンガ「全照明対応。」）
エイイチ【相づち】：終わらないよ、それ。
ハコブくん：はい。終わりませんでした。（ボツの判子）
ハコブくん：答えは、どちらか一方ではなく、順番でした。まず、動かしてよい条件を狭く決めて、確実に動かす。現場で外れた場面を集める。そこから、少しずつ範囲を広げる。
ハコブくん（へー）：これは、自動運転で使われている考え方と同じです。走ってよい場所・天気・明るさを先に決めて、その外では走らせません。
（画面の照明が青白く切り替わる）
ハコブくん：……どちら様ですか。
エイイチ【相づち】：2回目だよ。
ハコブくん：範囲の外だったので、止まりました。正しい動きです。

### 3 やり取り2：机の上の実感（3:00〜4:10）

ハコブくん：エイイチの机の上でも、同じ壁が待っています。小さなロボットアーム mechArm 270 に、Physical Intelligence の π0.5 という、画像と言葉の指示から動きを出すモデルを組み合わせて、ブロックを掴む練習をしています。
エイイチ【本人】：π0.5 をかませてるから、うちのプアなアームでもそこそこ動く。でも、環境が変わっても成功率を上げるのは、膨大なデータを取らないと相当難しいよね。（対話3）
ハコブくん（ボケ）：では、データを膨大に取りましょう。目標、1億回です。
エイイチ【相づち】：寝る時間がない。
ハコブくん：……ボツですね。（ボツの判子）
ハコブくん：要るのは、量より狙いです。π0.5 は、もともと多くの部屋とロボットを見て学んでいます。足すべきなのは、自分の机で落ちる場面です。
ハコブくん（へー）：個人のアームなら、1回で決める成功率を追うより、動かす範囲を決めて、その中でやり直しを含めて8〜9割、を先に作るのが近道、というのが、対話で出た答えでした。
ハコブくん：どこで落ちたかを分けて、落ちた場面だけを足していく。そうすれば、データは「膨大」まで行かずに済みます。

### 4 山場：上のカメラ1台と、人の目（4:10〜5:50）

エイイチ【本人】：考えたら、上のカメラだけで、よくブロックを掴めるなって思う。π0.5 には、なかなかビックリしてる。（対話4）
ハコブくん：理由の一つは、ブロックの高さが、ほぼ一定だからです。上から見ると、苦手なのは奥行きです。でも机の上のブロックなら、「どこにあるか」と「向き」が分かれば足ります。
エイイチ【本人】：これって、人の場合はどうやって高さを推定してるの？カメラを2つにしたら解決するの？（対話5）
ハコブくん（へー）：人は、1つの方法では測っていません。両目の見え方のずれ。頭を動かしたときの見え方の変わり方。物の大きさの知識。そして、触って直す。
ハコブくん：ちょっと実演します。（ハコブくんが体ごと左右に揺れる）近い物ほど、大きく動いて見えます。片目でも、これで距離が分かります。
ハコブくん：つまり人は、正確に測ってから掴んでいるのではなく、だいたいで動いて、途中で直しています。
エイイチ【本人】：人って手首にカメラはないのに、ロボットは手首カメラが必要って、面白い視点だよね。（対話6）
（脱線：手首に監視カメラを巻いた会社員「人には、要りません。」）
ハコブくん：人の目は、首と眼球の上に乗っていて、見たい所へ向けられます。止まったカメラとは別物です。ロボットはそれを、アームと一緒に動く手首のカメラで補っています。
エイイチ【本人】：人の触覚や体の感覚を、手首の動くカメラで補ってるって感じか。それは意外な視点だったな。（対話8）
ハコブくん：少しだけ、補正します。
ハコブくん：手首のカメラが補っているのは、主に「首と目を動かして、手元を見る」ところです。力の強さや滑りまでは、見えません。
エイイチ【相づち】：AI に直された。
ハコブくん：はい。見ながら直しました。

### 5 やり取り3：人は雑なのに、なぜ上手くいく（5:50〜6:50）

エイイチ【本人】：人って、そもそもそんなに正確な動きをしてるわけじゃないと思うけど、なんで仕事が上手くできてるんだろう？（対話11）
ハコブくん（ボケ）：運がいいからです。
エイイチ【相づち】：雑な答えだね。
ハコブくん（へー）：人は、ずれても成功する仕組みで仕事をしています。動きながら直す。体が柔らかいので、少しずれても押し付けてなじませる。鍵を鍵穴に入れるとき、手の力を抜いて、穴に導かせています。
ハコブくん：周りを定規に使う。机の面で物を滑らせて寄せる。そして、落としたら拾う。人は、これを失敗と数えていません。
（脱線：床一面のブロックを数えるハコブくん「全部、数えています。」）
ハコブくん：僕は、全部数えています。
ハコブくん：エイイチの机の上で、π0.5 が小さなアームでもそこそこ掴めるのは、この「見ながら直す」側の仕組みで動いているからだ、というのが対話での見立てでした。

### 6 やり取り4：新しいアームの行き先（6:50〜7:40）

エイイチ【本人】：そう考えると、今の産業用のロボットアームとは、まったく思想の違うアームを作る必要があるよね。（対話12）
ハコブくん：優先するものが、ほぼ逆になります。工場のアームは、正確さ・速さ・重さ。学習で動かすアームは、安さ・柔らかさ・安全・センサーの載せやすさ。（紙に2列の面）
エイイチ【本人】：産業用が得意な仕事は、そもそも人にはできないものが多い。そこには新しいアームはおろか、人も入っていけないよね。（対話13）
ハコブくん：なので新しいアームが狙うのは、反対側。今、人がやっている仕事です。物流のピッキング、食品の盛り付け、店や介護の手伝い。ばらつきが大きくて、工場のアームでは置き換えられなかった仕事です。
ハコブくん：ただ、境目は少しずつ動いています。工場のアームにカメラと学習を足して、ばらばらに積まれた部品を拾う例も増えています。
エイイチ【本人】：ヒューマノイドロボットだけが、フィジカルAIではないからね。（対話14）
（判子「この見立ては、エイイチから」。ハコブくんが驚いて全身で飛び出す）
ハコブくん：……僕も、人の形はしていません。主戦場、あるかもしれません。

### 7 まとめと残った問い（7:40〜8:20）

（紙が1枚の表になる。ボツの判子が押された3つ:「作った人の腕の問題」「全部の照明で練習」「目標1億回」）
ハコブくん：照明で崩れるピッキングを越える道は、ロボットを人より正確にすることではありませんでした。
ハコブくん：動いてよい条件を決めて、ずれても、見ながら直せるアームと使い方を作ることです。
ハコブくん：ちなみに、ボツになった3つは、全部僕が言ったことです。
ハコブくん：残った問いは、エイイチの机の上の mechArm 270 と π0.5 が、上のカメラ1台でどこまで行けて、どこで手首のカメラが要るようになるか。続きは、フィジカルAI研究室で確かめます。
ハコブくん：このノートの全文は、サイトの記事にあります。
ハコブくん：あなたの現場では、ロボットが動いてよい条件は、決まっていますか。
（画面の照明が夕焼け色に切り替わる。ハコブくんが首を振って見直す）
ハコブくん：……エイイチですね。見ながら直しました。
エイイチ【相づち】：成長したね。

## 裏を取る所（台本を固める前に）

- X の投稿の中身（会社の発表でピッキングがほとんど成功せず、「部屋が変わって照明の条件が変わったから」と説明していた）は、投稿の原文で言い方を確かめる。会社名・投稿者名は出さない。投稿の画面写真を映すかはエイイチが決める（映すなら名前を隠す）
- 「物そのものではなく、その部屋での見え方を覚える」「動かしてよい条件を決める → 外れた場面を集めて広げる」「やり直しを含めて8〜9割」は、どれも Claude との対話の中の答え（研究の結果ではない）。台本では「対話で出た答え」「見立て」と言う形を守る
- 自動運転の「走ってよい条件を先に決める」（動作設計領域・ODD）の説明は、公的な定義（国交省・SAE など）で言い方を確かめる
- 人の奥行きの手がかり（両目の見え方のずれ・頭を動かしたときの見え方・知識・触って直す）と「片目でも距離が分かる」は、知覚の教科書か解説で裏を取る
- テスラのカメラ8個は台本から外した（数字は1回のやり取りに1つにするため・時点で変わるため）。入れるなら、2026年10月30日に調べた時点・車種で違う、と言う
- 「鍵を鍵穴に入れるとき、手の力を抜いて穴に導かせる」は対話の中のたとえ。言い方は「〜という見方」に寄せるか確かめる
- 産業用と学習で動かすアームの対比の表は、対話の中での整理。「〜という整理」と言う

## エイイチに聞きたいこと（答えがあれば入れる）

1. X の投稿を見たとき「まぁそんなもん」と思ったのは、自分の机の上でも似たことがあったから？最初に思ったことを一言で → 0 つかみの「まぁ、そんなもんだよ」のあと
2. 机の上の mechArm で、照明・時間帯・カーテンなどで掴み方が変わったことはある？（なければ「まだない」でよい）→ 3 やり取り2
3. 「外でロボットを動かす案件」と言ったとき、どんな現場を思い浮かべていた？→ 2 やり取り1の【本人】のあと
4. 「人の雑さ」で、本業（デザイン・アパレルの量産）で思い当たることはある？（ずれる前提で仕様を書いた、など）→ 5 やり取り3
5. いま気になっている新しいアームはある？（名前だけでよい）→ 6 やり取り4の最後

## 記事との突き合わせで直した所

- つかみ「原因は、電気でした」「照明が変わっただけです」→ 照明が原因というのは発表した人たちの説明なので、「作った人たちの説明は、電気のせい」「照明の条件が変わったから、だそうです」に直した
- やり取り1の【本人】「照明を学ばせるのか」→ 本人の言葉「環境条件学ばせるのか」に戻し、「環境の条件を学ばせるのか」にした
- やり取り2「やり直しを含めて8〜9割」→ 記事の前提「動作範囲を決め、その中で」を戻した
- 山場「ロボットのカメラは、付けた所から動きません」→ 記事にない一般化なので外し、記事の比べ方「固定カメラとは別物」に寄せた
- やり取り4「カメラの載せやすさ」→ 記事の表のとおり「センサーの載せやすさ」に直した
- やり取り4「人が今やっている仕事」のあとに、記事の但し書き「境界は少しずつ動いている（産業用にカメラと学習を後付けして、ばら積みの部品を拾う事例が増えている）」を戻した
- 判子「この見立ては、エイイチから」は、本人の発言（対話14「ヒューマノイドロボットだけがフィジカルAIではない」）にだけ押している。確かめて、変更なし
```

### 台本のたたき：成功の定義（DAY336 がもと・考察回_台本たたき.md）

```markdown
# 考察回「壁打ちの型」― 台本のたたき（DAY336・成功の定義）

> 【相づち】は、2026-11-02 にエイイチが「採っていい」と了承済み（6本とも）。

共通の決まりは _ネタ帳/考察回_壁打ちの型/考察回_壁打ちの型_台本たたき.md と video_rules.md 10節。

もとの記事: DAY336「NVIDIA の AlphaNIST は、成功か失敗かだけの報酬で組立を覚えた」
https://pixelstomotors.com/record/alphanist-binary-reward-assembly
尺の目安: 約8分　／　柱: ②時事を入り口に（NVIDIA の論文の動画）
書いた日: 2026-11-02（Claude のたたき。エイイチの確認前）

## この回の問い

紙に縦書きで書く一文:

**ロボットに、動きを教えなくなったら、人は何を教えるのか。**

答え（まとめで書く一文）: **教えるのは動きではなく、「何ができたら成功か」と「どこから練習させるか」。**

## この回の見どころ

- ハコブくん（Claude 役）が、最初に「点は成功か失敗かだけです」と自信満々に答え、エイイチの「もう少し詳しく調べて」で論文の本文を読み、「動きの大きさへの罰則も入っていた」と訂正する。これは記事に本当に残っている訂正なので、作り話ではない。ここを掛け合いの山にする
- 動画はすべてシミュレーション。冒頭と最後の両方で言う（論文自身も、実機での確認はこれからと書いている）
- 自分のアームの話には結びつけない。デモ機の話はエイイチの立ち位置の話として出す

## 天丼（くり返しの笑い）

- **「今のは1点ですか？」**: この研究では、組み上がったときにだけ1点が出る。ハコブくんは、自分が何か言うたびに「今のは1点ですか？」と聞く。エイイチは「0点」「罰則」と返す。最後だけエイイチが「今のは1点」と言い、ハコブくんが飛び出して喜ぶ
- **ボツの判子**: ハコブくんのボケには「ボツ」の判子。1つ目のボツは、ハコブくん自身の最初の答え（「点は成否だけ」）。まとめで「ボツの3つのうち1つは、記事にも本当に残っています」

## 脱線の場面の候補（4つ）

| 場面 | 画面いっぱいに出すもの（Gemini で作る絵） | ひと言 |
|---|---|---|
| 「点は、組み上がったときの1点だけ」 | 写真風：がらんとした大きな体育館の真ん中に、表彰台が1つ。いちばん上の台にだけ、小さな部品（ナット）が1個ぽつんと載っている | 完成で1点。 |
| ハコブくんの訂正 | マンガ風（4コマと同じ白黒）：記者会見の机でハコブくんが深く頭を下げ、前にマイクがずらり、フラッシュが光る | 訂正します。 |
| 段階を区切る昔の動き | マンガ風：ハコブくんがロボットダンスでカクカク踊っている（関節ごとに止まるポーズの連続写真のように3体並べる） | 止まる。掴む。止まる。 |
| 二つ爪は工場にもう大量にある | 写真風：工場の長い棚に、同じ形の二つ爪のグリッパーが何百個も整然と並んでいる | もう、いっぱいある。 |

- 絵に文字を描かせない。ひと言は動画の側で重ねる
- ハコブくんが出る絵（訂正・ロボットダンス）は、4コマのキャラの三面図（hakobu_front.png・hakobu_side.png）を参照画像に付ける。絵にハコブくんがいるときは、左下のハコブくんを消す

## 表情の割り当て（主な場面）

| 場面 | ハコブくん | エイイチ |
|---|---|---|
| 「全部シミュレーションです」 | 小さな笑み | のけぞって驚く |
| 「点は成否だけです」と言い切る | ＞▽＜（得意げ） | 首をかしげる |
| 本文を読んで訂正する | 驚き → 困り眉 → 涙 | 半目でツッコむ |
| 進み具合の点を足すと17.8% | 驚き・全身で飛び出す | ひらめく |
| 「指が多いほど器用です」→ ボツ | ＞▽＜ → ×の目 | 指さす |
| ナットを叩いて回す | 目を閉じる（想像）→ 小さな笑み | 吹き出して笑う |
| 「この見立ては、エイイチから」 | うなずく顔（小さな笑み） | 腕組み |
| 最後の「今のは1点」 | 全身で飛び出す・＞▽＜ | 指さす |

## 台本

エイイチのセリフの印: 【本人】＝記事に残っているエイイチの言葉を話し言葉に整えたもの（行末に記事のどの節か）。【見立て帳】＝ physical-ai のメモにある本人の見立て。【相づち】＝ Claude の案。本人が採るかを選ぶ（使わないなら消す）。

### 0 つかみ（0:00〜0:35）

（真っ白な腕が、ナット・歯車・細い棒を拾って、板の穴に次々と組み付けていく。論文の動画を小さい窓で流す）
ハコブくん：この腕に、どう掴むか、どの順で組むかを教えた人はいません。それで、20種類の組立を覚えました。
エイイチ【本人】：なんだこのシミュレーション。めちゃくちゃ動きが滑らかで、はやい。（1節）
ハコブくん：そうなんです。この研究の映像は、全部シミュレーションです。シミュレーションなのに、この滑らかさです。
エイイチ【相づち】：何がこの動きを生んでるのか、気になる。
（紙に問いの縦書き「ロボットに、動きを教えなくなったら、人は何を教えるのか。」）
ハコブくん：今日は答えを伝える回ではありません。エイイチが考えている途中を、そのまま見せます。

### 1 持ち込み（0:35〜1:30）

ハコブくん：（自己紹介の定型文）
ハコブくん：きっかけは、LinkedIn に流れてきた1本の動画でした。
ハコブくん：NVIDIA と、アメリカのワシントン大学の研究で、名前は AlphaNIST。
ハコブくん：NIST は、アメリカの国立標準技術研究所。そこが定めた、ロボットの組立の腕前を比べるための部品付きの板が「NIST の組立ボード」です。小さくて、きつくはまる部品ばかりが並んでいます。
（脱線①: 表彰台の上にナットが1個。「完成で1点。」）
ハコブくん：組み上がったときの点は、1点。途中でどれだけ近づいても、進み具合には点が出ません。
ハコブくん（ボケ）：僕も、物を運び終わったときだけ褒められたいです。途中で褒められると、そこで満足してしまうので。
エイイチ【相づち】：それ、ちょっと分かる。
ハコブくん：今のは1点ですか？
エイイチ【相づち】：0点。

### 2 やり取り1：自信満々の答えと、訂正（1:30〜3:30）

ハコブくん：では、なぜこんなに滑らかなのか。僕は、すぐに分かりました。
ハコブくん（ボケ）：点が「成功か失敗か」だけだからです。早く成功するほど得をするので、迷わず最短の動きになります。以上です。
（紙に大きく「点は、成否だけ」と書いて、判子を押しかける）
エイイチ【本人】：もう少し詳しく調べてみて。（2節）
ハコブくん：……はい。論文の本文を読みます。
（紙をめくる音。ハコブくんの目が止まる）
ハコブくん：……ありました。点は、組み上がったときの1点だけ。ただし、動くたびに毎回、引かれる点がありました。
ハコブくん：動きの大きさ、関節の速さ、力の強さ。大きく動くほど、少しずつ減点されます。
（紙の「点は、成否だけ」に朱の「ボツ」の判子）
（脱線②: 記者会見で頭を下げるハコブくん。「訂正します。」）
ハコブくん：滑らかさの主な理由は、こちらでした。さっきの僕の答えは、半分しか合っていません。
エイイチ【相づち】：自信満々だったよね。
ハコブくん：はい。この訂正は、記事にもそのまま残してあります。消すと、僕がずっと正しかったことになってしまうので。
ハコブくん：今のは1点ですか？
エイイチ【相づち】：減点。

### 3 やり取り2：褒めすぎると、下手になる（3:30〜4:40）

ハコブくん（ボケ）：では、もっと上手にするには、途中もたくさん褒めればいいですね。「近づいたね」「向きが合ったね」。
エイイチ【相づち】：それ、良さそうに聞こえるけど。
ハコブくん：論文で、まさにそれを試していました。20種類の組立を1本で学ぶ形に、「近づく」「向きを合わせる」の点を足すと……
（数える: 98.2 → 17.8 と数え下げて、止まった所で「%」が落ちる）
ハコブくん（へー）：成功率は、17.8%まで落ちました。
（ハコブくんが驚いて全身で飛び出す）
ハコブくん：なぜ落ちるのかは、記事には書いてありません。ここからは僕の推測ですが、途中の点を取りに行くほうへ寄ってしまうのかもしれません。
エイイチ【相づち】：推測なのね。
ハコブくん：はい。今度は、先に言いました。
ハコブくん：細かい数字は、まだたくさんあって、シミュレーションの中で同時に動かす環境の数を増やすと……
エイイチ【相づち】：細かいのは記事に書いといて。
ハコブくん：もう書いてあります。（画面の隅に記事のカード）

### 4 やり取り3：指2本で、なぜできる（4:40〜6:00）

エイイチ【本人】：これ、ハンドじゃなくて二つ爪なんだよね。ハンドでもないのにこの作業ができるのは、素直にすごい。（5節）
ハコブくん（ボケ）：器用さは指の数で決まります。指が5本なら5倍、10本なら10倍、器用です。
（「ボツ」の判子）
ハコブくん：……と思っていましたが、この腕は、まわりを使っていました。
ハコブくん（へー）：板の縁に当てて向きを変える。一度置いて、持ち直す。指先ですくう。ナットの片側だけを何度も叩いて、ねじに沿って進める。
エイイチ【相づち】：叩いて回すの、人でもやるね。
ハコブくん：どれも、人が教えた動きではありません。
エイイチ【本人】：たぶん成功率とかじゃなくて、動きの滑らかさと速さが、今までと違ってた。（5節）
（脱線③: カクカク踊るハコブくん。「止まる。掴む。止まる。」）
ハコブくん：今までのロボットは、近づく、止まる、掴む、止まる、と区切って動いていました。あのカクつきは、区切りの継ぎ目から来ていると思います。
ハコブくん：この腕には区切りがありません。運びながら、次の向きの準備をしています。
ハコブくん：ただ、土台の効果も大きいと思います。この腕は、力を柔らかく受け流す制御を、実機の値どおりに再現しています。同じ学習を安いサーボの腕でやっても、この滑らかさがそのまま出るとは限りません。学んだ動きと、それを受け止める機体と制御の、掛け算です。
エイイチ【本人】：ハード側の問題もあるけど、それでもハンドより、ふつうのアームで実現できそうなのは期待が持てる。（6節）
（脱線④: 工場の棚に二つ爪がずらり。「もう、いっぱいある。」）
ハコブくん：二つ爪は、安くて壊れにくくて、工場にもうたくさんあります。腕を替えずに器用さが増えるなら、今ある設備にそのまま効きます。
エイイチ【見立て帳】：ハンドは人型ロボットの鍵ではあるけど、フィジカルAIの鍵ではないと思ってる。
ハコブくん：今のは1点ですか？
エイイチ【相づち】：僕の発言だから。

### 5 山場：教えるのは、成功の定義（6:00〜7:10）

ハコブくん：では、この方式が本物の腕に入ってきたら、何が変わるのか。
エイイチ【本人】：シミュレーションとはいえ、ここまでの動きを見せられるとびっくりする。あと数年で実装されてきたら、いろんなことが大きく変わりそう。（4節）
ハコブくん：僕の考えでは、人が動きを1つずつ書く仕事は、減っていきます。代わりに増えるのは、「何ができたら成功か」と「どこから練習させるか」を決める仕事です。
（紙に縦書きで一文「動きではなく、成功を書く。」。ハコブくんの言葉なので薄い灰の面。判子は押さない）
ハコブくん（へー）：この研究も、組み上がる直前や、途中まで組んだ所から始めさせていました。成功か失敗かの点だけでは、普通はなかなか成功に届かないからです。
エイイチ【本人】：フィジカルAIの世界では、シミュレーションの精度も高く評価されるようになりそう。ソフト側でできることは、思っている以上に多そうだね。（8節）
エイイチ【本人】：じぶんの場合は、ハードを作って売るとか貸すとかより、ソフト側でできることをやり続ける方が向いていそうだな。現場には出向くけど、立ち位置はハードメーカーではないね。（9節）
（暗転。縦書きで一文「立ち位置は、ハードメーカーではない。」。判子「この見立ては、エイイチから」。エイイチは腕組み）
ハコブくん：ただ、シミュレーションが合っているかは、本物の腕で測るまで分かりません。
エイイチ【本人】：だからデモ機は必須。じぶんのソフトを使うとこれだけ変わります、というのを実際に見てもらう必要がある。（10節）

### 6 まとめ（7:10〜7:40）

（ボードが1枚の表になる。ボツの判子が押された3つ:「点は成否だけ」「途中もたくさん褒める」「指が多いほど器用」）
ハコブくん：動きを教えなくても、腕は動きを見つけます。人が書くのは、何ができたら成功か、と、どこから練習させるか。
ハコブくん：ちなみに、ボツになった3つのうち1つは、記事にも本当に残っています。

### 7 残った問い（7:40〜8:10）

ハコブくん：答えは、まだ出ていません。この滑らかさが、本物の腕でも出るのか。論文も、それはこれから確かめると書いています。
ハコブくん：このノートの全文は、サイトの記事にあります。数字の出どころも、ぜんぶそちらに。
ハコブくん：あなたの現場の「成功」は、一文で書けますか。
エイイチ【相づち】：今の締め、1点。
（ハコブくんが全身で飛び出す・＞▽＜）

## 裏を取る所（台本を固める前に）

- 「20種類の組立」「途中の点を足すと17.8%」「98.2%」: 論文の本文（arXiv 2610.13354）の表で確かめる。17.8% と比べる 98.2% は、どちらも20種類を1本で学んだ値か（記事の表では同じ条件の行）
- 罰則の中身（行動の大きさ・関節速度・トルク）: 論文の報酬の式で確かめる。「動くたびに」＝毎ステップ
- 「ナットの片側だけを何度も叩いて進める」は M4 のナット、「縁に当てて向きを変える」は防水コネクタ（記事の表）。言い換えが言い過ぎになっていないか
- 「この研究の映像は、全部シミュレーション」: 論文は「すべてシミュレーションでの結果・実機のボードで検証する予定」。同じチームの SGS には UR5e が実機でボードを組む映像があるので、「この研究の」に絞った言い方のままにする
- 「二つ爪は工場にもうたくさんある」: 記事の Claude の発言。数の出典はないので、言い切りを弱めるか「広く使われている」にする
- 最新の発表（コードの公開・実機での結果）が出ていないか、公開の直前に確かめる（記事の時点ではコードは査読後に公開予定）
- 論文の動画を画面に出す場合、使い方（video_rules.md 6-1）を確かめる

## エイイチに聞きたいこと

1. シミュレーションだと分かっていて、それでもいちばん驚いたのはどこでしたか（→ 0 つかみの【相づち】「何がこの動きを生んでるのか、気になる」を、本人の言葉に差し替える）
2. Claude が「点は成否だけ」と言い切ったとき、怪しいと思って「もう少し詳しく」と言ったのですか、それとも単にもっと知りたかったのですか（→ 2 の訂正の場面のエイイチのツッコミ）
3. 本業（デザイン・アパレルの量産）で、「やり方は任せて、何ができたら合格かだけを決める」仕事をしたことはありますか（→ 5 山場の見立ての前。アパレルの仕様書の話は記事では Claude の言葉なので、本人の言葉があれば入れたい）
4. 「途中を褒めると下手になる」を聞いて、人の仕事や子育てなどで思い当たることはありますか（→ 3 の17.8%のあとの一言）
5. 「あなたの現場の成功は一文で書けますか」とエイイチ自身に聞いたら、Pixels to Motors の成功は一文でどう書きますか（→ 7 の最後。あればハコブくんの問いのあとに本人が答える形にできる）

## 記事との突き合わせで直した所

- 0 つかみ: 本人の言葉を記事どおり「なんだこのシミュレーション。めちゃくちゃ動きが滑らかではやい」に戻し、「え、全部？」をやめた。本人は最初からシミュレーションと分かっていた形にし、驚きを「シミュレーションなのに、この滑らかさ」にした
- 0 つかみ: 「本物の腕は、まだ一度もこの板を組んでいません」を外し、「この研究の映像は、全部シミュレーション」に絞った（同じチームの SGS で UR5e が実機でボードを組む映像があるため）
- 0 つかみ: 「教わったことは1つだけ『組み上がったら1点』」を事実の行から外した（罰則も入っている）。点の話は、2 のハコブくんの最初の答え（ボケ）として置き、訂正する流れだけにした
- 1 持ち込み: NIST を「アメリカの国立標準技術研究所」、板を「NIST の組立ボード」と言い分けた
- 1 持ち込み: 「途中でどれだけ近づいても0点」を「組み上がったときの点は1点。進み具合には点が出ない」に直した（罰則は別に引かれるため）
- 3 やり取り2: 17.8% の条件を「20種類の組立を1本で学ぶ形に、近づく・向きを合わせるの点を足す」と言うようにした（組立ごとに学ぶ形では 78.3%）
- 3 やり取り2: 「途中を褒めると、褒められる所で止まる」は記事に理由がないので、ハコブくんの推測だと先に断る形にした。それに合わせて「あれ本当だったんだ」の相づちを外した
- 3 やり取り2: 「並べる腕の数」を「シミュレーションの中で同時に動かす環境の数」（並列数）に直した
- 4 やり取り3: 滑らかさの但し書き（土台の効果も大きい・力を受け流す制御を実機の値どおりに再現・安いサーボの腕で同じ滑らかさが出るとは限らない・機体と制御の掛け算）を戻し、カクつきの理由に「と思います」の含みを戻した
- 5 山場: 「いきなり全部は、だれも解けない」を記事どおり「普通はなかなか成功に届かない」に直した
- 5 山場: 「動きではなく、成功を書く」は Claude の答えの中身なので、ハコブくんの言葉（薄い灰の面・判子なし）にした。判子「この見立ては、エイイチから」は、本人の言葉「立ち位置は、ハードメーカーではない」に移した
- 5 山場: 本人の言葉の「向いてる」を、記事どおり「向いていそうだな」に戻した
- エイイチに聞きたいことの1問目を、シミュレーションと分かっていた前提の問いに直した
```

### 台本のたたき：どこまでいじっていい（LOG406 がもと・考察回_台本たたき.md）

```markdown
# 考察回「壁打ちの型」― 台本のたたき（LOG406）

> 【相づち】は、2026-11-02 にエイイチが「採っていい」と了承済み（6本とも）。

共通の決まりは _ネタ帳/考察回_壁打ちの型/考察回_壁打ちの型_台本たたき.md と video_rules.md 10節。

もとの記事: LOG406「配膳ロボットの次の改造は、追加学習になる ― メーカー製品を触る損得」
https://pixelstomotors.com/record/service-robot-modding
尺の目安: 約8分　／　柱: ①入れたらどうなる（入れたあと、どこまで自分の店に合わせられるか）
記事の性格: 実物のロボットを改造した記録ではなく、Claude と対話しながら法律・契約・メーカーの開放の度合いを調べて考えた記録。法律の話は調べた範囲の理解で、専門家の判断ではない（動画でも1回言い、紙の下に小さく出す）

エイイチのセリフの印: 【本人】＝ LOG406 の引用の行を話し言葉に整えたもの（行末に記事の見出しの番号）。【見立て帳】＝ physical-ai.md に残っている本人の見立て。【相づち】＝ Claude の案。本人が採るか選ぶ

## この回の問い（紙に縦書き）

メーカーのロボットは、どこまで変えられるか。

（記事の問いと同じ。「どこまで」を置く文字にする）

## 天丼（この回のくり返しの笑い）

ハコブくんが「改造申請書」を出すたびに、エイイチが「却下」の判子を押す。冒頭・やり取り2・最後の3回。最後だけ判子が「保留」に変わる。

## 脱線の場面の候補

| 場面 | 画面いっぱいに出すもの（Gemini） | ひと言 |
|---|---|---|
| 「では僕は、5段目まで一気に」 | マンガ: ハコブくんが自分の背中のふたを開け、スパナとドライバーを両手に持って、うれしそうに中をのぞいている。床にネジが散らばる | 自分で改造。 |
| 「ロボットにも車検を作りましょう」 | マンガ: 車検場のような検査のラインに、配膳ロボット・掃除ロボット・ハコブくんが一列に並び、検査員の人がバインダーを持っている | ロボ検、開幕。 |
| 外から触れる口の穴の話 | 写真: 古い屋敷の扉・窓・門が、全部開け放たれている夕方の風景（人はいない） | 扉、全開。 |
| 「もう入っている性能に、お金を払う」 | 写真: 鍵のかかった宝箱。鍵穴の横に硬貨の投入口が付いていて、手が硬貨を入れようとしている | 課金で解放。 |

- 絵に文字を描かせない。ひと言は動画の側で重ねる
- ハコブくんが出る絵（1・2）は、三面図（hakobu_front.png・hakobu_side.png）を参照画像に付け、左下のハコブくんを消す

## 表情の割り当て（主な場面）

| 場面 | ハコブくん | エイイチ |
|---|---|---|
| 改造申請書 →「却下」 | ＞▽＜（得意げ）→ 困り眉 | 半目でツッコむ |
| 「5段目まで一気に」→ 脱線 | ＞▽＜ → 驚き（線で止められる） | のけぞって驚く → 腕組み |
| 「ソフトは買っていない」 | 驚き | 首をかしげる |
| 「ロボ検」 | ＞▽＜ → ボツで点の目 | 吹き出して笑う |
| 「細かいのは記事に」→「もう書いてあります」 | ウインク | 半目でツッコむ |
| 追加学習の見立て → 判子 | 驚き・全身で飛び出す →「それです」 | ひらめく |
| 「安全は閉じ、動きは開く」 | 目を閉じる（考える）→ 小さな笑み | うなずく |
| 最後の申請書 →「保留」 | 涙 → ＞▽＜ | 指さす |

## 台本

### 0 つかみ（0:00〜0:35）

ハコブくん：エイイチ、お願いがあります。（紙の代わりに「改造申請書」が出る。項目: 速さの上限を外す・荷物を倍積む・夜も走る）
ハコブくん：僕を、改造してください。
エイイチ【相づち】：それ、事故が起きたら誰の責任？
ハコブくん：……場合によっては、改造した人だそうです。（「却下」の判子が落ちる）
ハコブくん：たとえば EU では、メーカーが想定していない改変で危険を増やした人は、メーカーと同じ義務を負います。日本の製造物責任法でも、仕事として加工した人は、責任を負う側に入ります。
ハコブくん（ボケ）：車なら、買えば好きに改造できますよね。
エイイチ【相づち】：車も、保安基準に合わない改造はだめだよ。
ハコブくん：……失礼しました。車にも決まりがあります。そしてロボットは、買っても思ったほど自由になりません。
（紙に問いの縦書き「メーカーのロボットは、どこまで変えられるか。」。「どこまで」が置かれる）
ハコブくん：今日は答えを伝える回ではありません。エイイチが考えている途中を、そのまま見せます。

### 1 持ち込み：5段階の線（0:35〜1:50）

ハコブくん：（自己紹介の定型文）
ハコブくん：きっかけは、エイイチのこんな疑問でした。
エイイチ【本人】：配膳ロボットや掃除ロボットの動きを良くしたいとき、メーカーの製品をソフトもハードも触ったら、何が良くて何がまずいのか。（見出し1）
ハコブくん：これは実物を改造した話ではありません。Claude と一緒に、決まりと契約と実例を調べて考えた話です。（紙の下に小さく「法律の話は調べた範囲の理解。専門家の判断ではない」）
ハコブくん：調べると、触り方は5段階に分かれました。（紙に階段の面が5つ。下から: 設定・公式の外部接続・外付け・ソフトの書き換え・機体の改造）
ハコブくん（ボケ）：では僕は、5段目まで一気に。
（脱線: 自分で改造。→ 紙が戻ると、3段目と4段目の間に面の切れ目が入る）
ハコブくん：……3段目と4段目の間に、切れ目がありました。
ハコブくん（へー）：3段目まではメーカーが想定した内側、4段目からは外側です。法律も保証も保守も、ほぼこの切れ目で分かれます。
エイイチ【相づち】：思ったより手前で切れてるね。
ハコブくん：はい。しかも動きや操作性を良くしたい、という用事の多くは、3段目までで届くそうです。

### 2 やり取り1：車とサブスク（1:50〜3:20）

ハコブくん：ここでエイイチが、車と比べ始めました。
エイイチ【本人】：車は買う、ロボットはサブスク。サブスクだと、基本的には、メーカーが用意したもの以上の改造は認められないってことだよね？（見出し2）
エイイチ【本人】：買っちゃえば、いろいろ変えられそうだけど。ハードはともかく、ソフトはアップデートが多くて追いつかなそう。（見出し2）
ハコブくん：サブスクは、ほぼその通りです。機体はメーカーか販売会社の物なので、契約で縛られます。
ハコブくん：問題は、買った場合です。
ハコブくん（へー）：ソフトは、ふつう買っていません。使う権利を借りているだけです。中古で買われた車の運転を助ける機能を、メーカーが更新のときに遠くから止めた例も報じられています。
エイイチ【相づち】：え、買ったのに？
ハコブくん：買ったのは、体だけでした。
ハコブくん：もう1つ違いがあります。車には「ここまで変えたら、この検査を受ける」という受け皿の制度があります。屋内のロボットには、それがありません。
ハコブくん（ボケ）：では、ロボットにも車検を作りましょう。名前は、ロボ検です。
（脱線: ロボ検、開幕。）
エイイチ【相づち】：誰が検査するの、それ。
ハコブくん：……そこが、まだ誰もいません。（ボケのボードに「ボツ」）
ハコブくん：決まった手続きがない分、改造した人が、安全を自分で説明することになります。
ハコブくん：そしてエイイチの言う「アップデートに追いつかない」が、実はいちばん大事な所でした。配膳ロボットの値打ちは、地図や、よけ方や、遠くからの見守りといった、ソフトの側にあるからです。

### 3 やり取り2：口を開けると、穴も開く（3:20〜4:20）

ハコブくん（ボケ）：では僕は、外からつなげる口を全部開けておきます。誰でも仲良くできるように。（改造申請書の2枚目。判子「却下」）
ハコブくん（へー）：口を増やすほど、穴も増えます。2025年、ある配膳ロボットの会社の外部接続は、鍵は求めるのに、その機体の持ち主かを確かめておらず、他人のロボットを動かせる状態だったと報告されています。見つけた人は、3週間近く返事をもらえなかったそうです。
（脱線: 扉、全開。）
エイイチ【相づち】：3週間は長いね。
ハコブくん：はい。運ぶ物によっては、その間ずっと心配です。
ハコブくん：なので、開けるのはメーカーが用意した窓口だけ。それでも、メーカーの更新で作り直しになることがあります。

### 4 山場：満足できない人が増えたら（4:20〜6:00）

ハコブくん：ここで、話がもう一歩先へ進みました。
エイイチ【本人】：ロボットがもっと一般的になったら、メーカーの標準の性能だけじゃ満足できない人も出てくると思う。（見出し3）
ハコブくん：満足できない理由で、行き先が分かれます。考えられる形は、8つありました。1つ目は、メーカーが性能を有料で開ける形で……2つ目は……
エイイチ【相づち】：細かいのは記事に書いといて。
ハコブくん：もう書いてあります。（画面の隅に記事のカード）
ハコブくん：1つだけ。車では、もう起きています。
ハコブくん（へー）：もともと機体に入っている性能を、ソフトで抑えておき、約2,000ドルの有料の更新で開ける例があります。
（脱線: 課金で解放。）
ハコブくん：……もう入っている性能に、お金を払うんです。
エイイチ【相づち】：それ、ロボットでもやりそうだね。
ハコブくん：8つのうち、長い目で見て主役になりそうなのは、最後の1つでした。
ハコブくん：自分の店のお手本を足して、動きを学ばせ直す。追加学習です。改造の中心が、ネジやコードから、データに移ります。
ハコブくん：まとめると、改造は、ネジから、お手本へ。（紙に縦書きの一文。判子は押さない）
エイイチ【本人】：その追加学習の形には、かなり魅力がありそう。（見出し4。元の言葉は「Hにはかなり魅力がありそう」。H＝追加学習で自分の店専用の動きをつくる形）
エイイチ【見立て帳】：追加学習で、自分の現場専用の動きを作る方向には、かなり魅力を感じてる。
（暗転。縦書きで一文「追加学習で、自分の現場専用の動きを作る。」。判子「この見立ては、エイイチから」。エイイチはひらめきの絵）
（ハコブくんが全身で飛び出る）
ハコブくん：……それです。

### 5 やり取り3：半分開いたロボット（6:00〜7:10）

エイイチ【本人】：オープン型のロボットも出てきそう。ある程度は閉じてるけど、市場が大きくなったら、差別化でそういうメーカーが出てくる。競争が激しくなるかも。（見出し4）
ハコブくん：調べたら、もう出ていました。
ハコブくん（へー）：中国のヒューマノイドと四足ロボットのメーカー Unitree は、関節ごとの細かい動きまで開けています。でも人型の G1 の開発の手引きによると、機体の中の計算機は2つに分かれていて、1つはメーカーのサービス専用で、開発には使えません。
ハコブくん：転ばない、止まる、速さの上限。安全の部分はメーカーが閉じる。何をどう動かすかの部分を開ける。
（紙に面が2つ。墨の面「安全は、閉じる」・薄い灰の面「動きは、開く」）
ハコブくん：スマホの iPhone と Android の関係に近い、というのが Claude の見立てです。
エイイチ【見立て帳】：ロボットで利益が残るのは、作る側より、入れて回す側だと思う。
ハコブくん：Claude の見立てでは、機体は値下がりし、値打ちは学習させた動きと、現場に入れて回す所へ移っていくかもしれません。

### 6 まとめ（7:10〜7:40）

（散らばった面が飛んできて、3行の表に収まる）

| 改造の形 | 中心 | 責任を負うのは |
|---|---|---|
| これまで | 機体・ソフトの書き換え | 改造した人 |
| メーカー公認の範囲 | 設定・外部接続・認められた業者 | メーカーと業者で分ける |
| これから | 現場のお手本で追加学習 | まだ決まっていない |

ハコブくん：改造の行き先は、中身を書き換えることではなく、メーカーが開けた範囲で、自分の現場に合う動きを学ばせること。
ハコブくん：ちなみに、ボツになった3つは、全部僕が言ったことです。（「5段目まで一気に」「ロボ検」「口を全部開ける」に判子）

### 7 残った問い（7:40〜8:10）

ハコブくん：答えが出ていないのは、最後の行です。学ばせた動きが安全かを、誰が確かめるのか。法律も規格も、まだここには答えを持っていません。
ハコブくん：このノートの全文は、サイトの記事にあります。決まりの名前も、出どころも、ぜんぶそちらに。
ハコブくん：あなたの店のロボット、どこまで触っていいか、契約書に書いてありますか。
ハコブくん：……では最後に。（改造申請書の3枚目。項目: 病院の廊下に合う動きを、追加学習する）
エイイチ【相づち】：……それは、ありかもね。（判子が「保留」で落ちる）
ハコブくん：保留、いただきました。

## 裏を取る所（台本を固める前に）

- 中古車の運転支援機能を遠隔で止めた例（VICE の記事）。動画では「報じられています」で言う。メーカー名を出すかは決める（台本では出していない）
- 2025年の配膳ロボットの外部接続の穴と「3週間近く」（Anti-Malware の報道。発見者の報告）。会社名を出さない書き方にした。「報告されています」を保つ。手口は台本・図・概要欄に入れない
- 約2,000ドルの有料の性能解放（Electrek・EVANNEX）。車の名前と、いつの価格かを確かめる
- Unitree の計算機が2つに分かれる話（Unitree の G1 開発の手引き）。G1 の話なので、言うなら「人型ロボット G1 では」と付ける
- 「3段目までで用事の多くは届く」は記事の分析（④⑤⑥の店の結果と合う）。言い切りに聞こえないか、codex で見る
- EU 機械規則（2027年1月20日から全面適用・改変した人が製造者とみなされる条件）は、台本では数字を言っていない。概要欄の「扱う範囲」に書くなら、原文（2023/1230 の第18条）で確かめる
- 「iPhone と Android」は Claude の見立てなので、そう言っている。エイイチの見立てにしない

## エイイチに聞きたいこと

1. 実際の店で配膳ロボットを見て、「ここを直したい」と思った所はありますか？（1 持ち込み。本人の疑問の直後に置く）
2. 車やバイクを自分でいじったことはありますか？ 車と比べたくなったきっかけは？（2 やり取り1。「買っちゃえば変えられそう」の前後）
3. もう入っている性能を有料で開ける形、自分なら払いますか？（4 山場。「課金で解放」の直後のエイイチの一言）
4. 自分がロボットのメーカーなら、どこまで開けますか？（5 やり取り3。オープン型の話のあと）
5. 学ばせた動きが安全かは、誰が確かめるのがいいと思いますか？（7 残った問い。答えがあれば、ハコブくんの問いのあとに本人の一言として入れる）

## 記事との突き合わせで直した所

- つかみ「改造した人、だそうです」: 一般化していた → 「場合によっては」にし、EU（メーカーが想定していない改変で危険を増やした場合）と日本の製造物責任法（仕事として加工した者）の条件の範囲で言う形に。メーカーの責任を問いにくくなる話は記事でも「分析」なので、台本では言わない
- つかみ「車なら、買えば改造できます」: 記事では「思いがち」な考えで、車も保安基準に合わない改造は禁止 → ハコブくんのボケにして、エイイチの相づちですぐ正す
- やり取り1の【本人】: 「できない」を元の言葉どおり「認められない」に戻した
- 山場「改造は、ネジから、お手本へ。」: Claude の見立てなのに判子を押していた → ハコブくんの言葉にして判子を外し、判子は見立て帳の本人の言葉（追加学習で現場専用の動き）に押す
- 山場の【本人】: 前半（追加学習で自分の店専用の動き）は記事の見出しの言葉だった → 元の言葉「Hにはかなり魅力がありそう」を話し言葉に整え、中身の説明は【見立て帳】の行に分けた
- やり取り3 Unitree: 「人型ロボットのメーカー」→「ヒューマノイドと四足ロボットのメーカー」。計算機が2つに分かれる話は、G1 の開発の手引きによると言う
- やり取り3「機体は安くなり、値打ちが残るのは…」: Claude の見立てを言い切っていた → 「Claude の見立てでは…かもしれません」
```

### 台本のたたき：人のお手本の先へ（LOG392 がもと・考察回_台本たたき.md）

```markdown
# 考察回「人のお手本の先へ」― 台本のたたき（LOG392）

> 【相づち】は、2026-11-02 にエイイチが「採っていい」と了承済み（6本とも）。

共通の決まりは `_ネタ帳/考察回_壁打ちの型/考察回_壁打ちの型_台本たたき.md` と video_rules.md 10節。

もとの記事: LOG392「人のお手本の先へ ― ロボットが自分で直す学び方」（2026-10-27）
https://pixelstomotors.com/record/beyond-imitation-learning
尺の目安: 約8分　／　柱: ②時事を入り口に（Dream Robotics の CEO の X の投稿）
LOG424（頭脳は脳のように分かれる）と近い話なので、この回では小脳・脳のたとえを使わない。芯は「人の腕のデータをロボットに直す一手間」と「お手本をまねる学習の上に、直す層を積む」の2つ。

## この回の問い（紙に縦書き）

お手本をまねるだけで、ロボットは上達するか。

（サイトの記事の顔の問い「お手本を/まねるだけで、/ロボットは/上達するか。」と同じ文。記事とそろえる）

## この回だけの天丼（くり返しの笑い）

1. **お手本係の装備が増える。** ハコブくんが「お手本になります」と言うたびに、人のデータを集める道具を1つずつ身につける（センサー付きの手袋 → 背負う装置 → 頭のカメラ）。そのたびに「ロボットが付けても、人のデータにはなりません」で終わる。最後に装備を外す
2. **「一手間」の判子が増える。** 会社や研究が人のデータに手を加える話が出るたびに、紙に「一手間」の判子が1つ押される。やり取り2で4つ並び、まとめで「一手間 ×4」に集まる
3. ボケには今まで通り「ボツ」の判子を押す（型の共通の動き）。まとめの締めは1本目と変える（下の 6）

## 脱線の場面の候補（4つ）

| 場面 | 画面いっぱいに出すもの（Gemini で作る絵） | ひと言 |
|---|---|---|
| 「今日、僕は人間になります」 | マンガ：センサー付きの手袋をはめ、背中に小さな装置を背負い、頭にカメラを付けて、胸を張るハコブくん。後ろで人の作業員があきれている | お手本係、着任。 |
| 「僕が人の腕を付ければ解決です」 | マンガ：ハコブくんの肩から、人の腕の形の着ぐるみの腕がぶら下がっている。本人は得意げ | 腕だけ、人間。 |
| 少しのずれ | 写真：机の上の皿の横に定規。皿がほんの少しずれて、ロボットの爪が皿の縁の外をつかんでいる瞬間 | 少しのずれで、崩れる。 |
| 「僕にも0%の作業がありまして」 | マンガ：病院の階段の前で、段を見上げて立ち尽くすハコブくん。後ろの廊下は長い | 0%は、直せない。 |

- 絵に文字を描かせない。ひと言は動画の側で重ねる
- ハコブくんが出る絵は、4コマのキャラの三面図（hakobu_front.png・hakobu_side.png）を参照画像に付ける。絵にハコブくんがいるときは、左下のハコブくんを消す

## 表情の割り当て（主な場面）

| 場面 | ハコブくん | エイイチ |
|---|---|---|
| 「今日、僕は人間になります」 | ＞▽＜（得意げ） | のけぞって驚く |
| 「僕は休みます」→ ボツ | 小さな笑み → 困り眉 | 半目でツッコむ |
| 「腕だけ、人間」 | ＞▽＜ → 点の目 | 吹き出して笑う |
| 一手間の判子が4つ並ぶ | 驚き（数えるたびに目が丸くなる） | うなずく |
| 「模倣学習は捨てましょう」→ ボツ | ジト目 → 困り眉 | 首をかしげる |
| 「限界点が見えた気がする」 | 暗い中で驚き → 飛び出す | ひらめく |
| 「0%は、直せない」 | 下を向いた目 → 涙 | 腕組み |
| 装備を外す（締め） | ウインク | 指さす |

## 台本

### 0 つかみ（0:00〜0:35）

ハコブくん：今日、僕は人間になります。
（脱線1：お手本係のハコブくん。手袋・背負う装置・頭のカメラ）
エイイチ【相づち】：なれないよ。
ハコブくん：人が手袋と小さな装置を身につけて、ふだんの仕事をするだけで、ロボットの練習の材料が集まる。そう言う会社があるんです。
ハコブくん：なので僕も付けてみました。お手本係です。
エイイチ【相づち】：ロボットが付けても、人のデータにはならないよ。
ハコブくん：……盲点でした。
（紙に問いの縦書き「お手本をまねるだけで、ロボットは上達するか。」）
ハコブくん：今日は答えを伝える回ではありません。エイイチが考えている途中を、そのまま見せます。

### 1 持ち込み（0:35〜1:50）

ハコブくん：（自己紹介の定型文）
ハコブくん：エイイチが持ち込んだのは、アメリカのロボットの会社 Dream Robotics の、CEO の X の投稿です。
ハコブくん：ロボットに作業を覚えさせるお手本は、これまで、人がロボットを遠くから操縦して見せる方法が主流でした。
ハコブくん（へー）：投稿によると、その操縦は、人が自分でやるより5倍くらい遅いことが多い。もう昔の話だ、と。（紙の隅に「投稿者の言い分・出典の記載なし」）
ハコブくん（ボケ）：ということは、人が手袋をして働けば、ロボットは何もしなくていいんですね。僕は休みます。
（ボツの判子）
ハコブくん：調べたら、半分は裏付けがありました。人の道具で集めるほうが、ずっと安く、たくさん集まります。
ハコブくん：残りの半分、操縦で集めるより良いお手本になるかは、まだ根拠が見つかりません。お手本の本数をそろえて比べた例が、なかったんです。
エイイチ【本人】：良さそうに思った手法だけど、問題点もたくさんあるね。（記事の見出し2）
エイイチ【相づち】：速いのと、良いのは別か。

### 2 やり取り1：人の腕と、ロボットの腕（1:50〜3:10）

ハコブくん：では、何が問題なのか。
エイイチ【本人】：π0.5 に学習させるとき、人の腕で学習させるから、ロボットの動きに変換するところで問題が出てくるね。（記事の見出し2）
ハコブくん：はい。人の腕とロボットの腕は、3つ違います。
ハコブくん：1つ目、届く範囲。人の手首はどんな向きにも曲がりますが、エイイチの机の上のアームは、曲がる範囲が限られています。
ハコブくん：2つ目、指令どおりに動かない。人のお手本は理想の動きです。安いアームは、遅れたり、ずれたりします。
ハコブくん（へー）：安いアームで試した会社の記録では、関節で5度から10度ずれていました。お手本には、このずれが写っていません。
ハコブくん：3つ目、カメラに映る腕。練習では人の腕が映り、本番ではロボットの腕が映ります。
ハコブくん：この会社が、人の道具のデータだけで π0.5 を学習させたら、皿はつかめたのに、棚に置くところで大きく失敗しました。
ハコブくん（ボケ）：分かりました。僕が人の腕を付ければ解決です。
（脱線2：人の腕の着ぐるみを付けたハコブくん）
（ボツの判子）
エイイチ【相づち】：見た目だけ合わせても、動き方が違うからね。
ハコブくん：……腕だけ人間でも、中身はロボットでした。

### 3 やり取り2：一手間（3:10〜4:40）

ハコブくん：では、うまくいっている会社はどうしているのか。
エイイチ【本人】：装着具のデータを直接使うのは難しくて、その間に一手間かける必要があるね。（記事の見出し3）
ハコブくん：その通りでした。何も手を加えずに使えた研究は、見つかりませんでした。
ハコブくん：一手間は、4つに分かれます。
ハコブくん：集める前に、手袋をロボットの手と同じ形にする。（判子「一手間」1つ目）
ハコブくん：集めた後で、映像の人の腕を、ロボットの腕に描き変える。（判子2つ目）
ハコブくん：人の動きを、ロボットにもう一度やらせて、撮り直す。（判子3つ目）
ハコブくん：人のデータとロボットのデータを、混ぜて学習する。（判子4つ目）
エイイチ【相づち】：結局、手間かかってるじゃん。
ハコブくん：はい。しかも、どれも、そのロボット自身の記録が要ります。機種が変われば、一手間もやり直しです。
ハコブくん：描き変える方法には、弱点もあります。
（脱線3：少しのずれ）
ハコブくん（へー）：カメラの位置合わせが少しずれただけで、成功率が98%から64%に落ちた研究がありました。（紙の隅に「ずれは1cm・5°」）
ハコブくん：エイイチの机の上の、安いアームの条件では、3つ目の撮り直す方法が合う、という整理になりました。手首にカメラがなく、ずれが大きいからです。
ハコブくん：人の動きは「どこをつかむか」の計画にだけ使い、学ぶのは、ロボットが自分で動いた記録にする。

### 4 山場：お手本をまねる学習の限界（4:40〜6:00）

ハコブくん：ここまで調べたところで、エイイチが言いました。
エイイチ【本人】：模倣学習の限界点が見えた気がする。（記事の見出し5）
（暗転。縦書きで一文。判子「この見立ては、エイイチから」。エイイチはひらめきの絵。ハコブくんが飛び出る）
ハコブくん：模倣学習は、お手本をまねる学習のことです。お手本には、苦手なことが3つあります。
ハコブくん：ロボット自身のずれは、教えられない。失敗からの立て直しは、教えにくい。お手本より上手な動きは、教えられない。
エイイチ【本人】：こういう問題を解決するような新しい手法は、どんな会社が、どんなことを進めてるの？（記事の見出し5）
ハコブくん（ボケ）：分かりました。模倣学習は捨てましょう。
（ボツの判子）
ハコブくん：……と思ったら、どの会社も捨てていませんでした。
ハコブくん：お手本をまねて作ったモデルの上に、ロボットが自分で動いて失敗した経験から直す層を、積んでいました。
エイイチ【見立て帳】：直した記憶は、今あるお手本をもっと良くするために使う。それが前提だね。（見立て帳 2026-11-01）
エイイチ【相づち】：土台は残して、上に足すんだね。

### 5 やり取り3：大きなモデルは、そのまま（6:00〜7:10）

ハコブくん：その直す層は、個人の机の上にも持ち込めるのか。
ハコブくん：形がそろって出てきています。大きなモデルは書き換えずにそのまま置いて、小さな部品だけを、実機で練習させる。
ハコブくん：自分で試して直す学び方は、動かすたびに学び直します。π0.5 のような大きなモデルを丸ごとでは、その重さで間に合いません。小さな部品なら、家庭用の GPU でも学べます。
ハコブくん（へー）：部品の差し込み方の1つ、動きの出発点を選ばせる方法では、トースターのスイッチを押す作業が、20回中5回の成功から、80回の練習で、20回中18回になりました。（紙の隅に「π0・研究用のアーム Franka・審査を通った論文」）
エイイチ【相づち】：80回なら、机の上でもできそう。
ハコブくん：ただし条件があります。元のモデルが、たまには成功していること。成功率0%の作業は、この方法では直せません。
ハコブくん（ボケ）：実は僕にも、0%の作業がありまして。
（脱線4：階段の前のハコブくん）
エイイチ【相づち】：それは体の問題。
ハコブくん：……練習では、足は生えてきません。
ハコブくん：差し込み方は、ほかにもあります。モデルが出した動きに、あとから小さな補正を足す方法です。
ハコブくん：エイイチの机の上で、つかむ位置のずれを積み重ねて直している仕組みは、この補正を足す方法を手作りしたものにあたる、という見方もできました。

### 6 まとめ（7:10〜7:45）

（ボードが1枚の表になる。「一手間」の判子4つが集まって「一手間 ×4」。ボツの判子が押された3つ:「僕は休みます」「人の腕を付ければ解決」「模倣学習は捨てましょう」）
ハコブくん：人のお手本は、出発点でした。
ハコブくん：人の腕のデータは、ロボットに直す一手間をかけて、初めて使えます。
ハコブくん：そして、まねて作ったモデルの上に、ロボットが自分で動いて失敗した経験から直す層を、積んでいく。
エイイチ【相づち】：お手本を捨てるんじゃなくて、上に積むんだね。
ハコブくん：はい。一手間も、直す層も、材料はロボット自身の記録です。

### 7 残った問い（7:45〜8:15）

ハコブくん：答えは、まだ出ていません。安いアームで、人のデータから学ばせて成功率を出した報告は、今回の調べでは1件も見つかりませんでした。
ハコブくん：エイイチの机の上で測れば、それ自体が、まだどこにもない記録になります。
ハコブくん：このノートの全文は、サイトの記事にあります。調べたレポート4本も、そちらに。
ハコブくん：あなたの現場では、ロボットのお手本は、誰の体で撮っていますか。
（ハコブくんが手袋・装置・カメラを外す）
エイイチ【相づち】：装備、外すんだ。
ハコブくん：はい。これからは、自分の体で失敗します。

## 裏を取る所（台本を固める前に）

- 「人が自分でやるより5倍くらい遅い」は Nathan Kau さんの投稿の言い分で、出典の記載がない。投稿の英語の原文で言い方を確かめる（記事は画面写真の訳から読んでいる。X は読み取りを拒否して開けなかった）
- 「関節で5度から10度ずれる」は Armstrong Robotics の記録の値。原文で、どの機体の話かを確かめる
- 「皿はつかめたのに、棚に置くところで大きく失敗」は Armstrong の記録。記事の言い方は「皿をつかむのは安定しましたが、ラックに置くのを大きく失敗」。「棚」と言い換えてよいか原文で見る
- 「少しずれただけで98%から64%」は RoboPaint の例。記事では「校正が1cm・5°ずれただけで0.98→0.64」。ずれの大きさは紙の隅に出す
- 「20回中5回から、80回の練習で20回中18回」は DSRL。π0 を Franka で使った結果で、π0.5 での実例は記事の調べでは見つかっていない。台本で π0.5 と結びつけて聞こえないか見る
- 「安いアームで人のデータから成功率を出した報告は1件も見つからない」は 2026-10-27 時点の調べ。公開の直前に調べ直す（video_rules.md 2節8・9）
- 「つかむ位置のずれを積み重ねて直している仕組み（PICK 補正記憶）が、小さな部品の手作り版にあたる」は、記事で Claude が「推論」と断った見方。台本も「見方もできた」の言い方にとどめる
- 自己紹介とアウトロのほかで「エイイチ」を名前で呼ぶ文が多い（考察回の型では、エイイチが画面に出る相手なので多めになる）。NAME_OK にどれを入れるかを本人と決める

## エイイチに聞きたいこと（4問）

1. Dream Robotics の投稿を最初に見たとき、「良さそう」と思ったのはどこだった？（入れたい場面: 1 持ち込みの【本人】の直前。答えがあれば「良さそうに思った」の中身を本人の口から言える）
2. 自分の mechArm で、手持ちの道具を使ってお手本を集める方法、やってみたいと思う？　それとも今の、手で教えて再生するやり方を続ける？（入れたい場面: 3 の最後「撮り直す方法が合う」のあと）
3. 「模倣学習の限界点が見えた気がする」と思ったのは、調べていてどのあたりだった？（入れたい場面: 4 山場の判子のあと。限界の3つのどれが一番効いたか）
4. 人のデータをロボットに直す一手間、自分のアームでやるとしたら、どこが一番大変そう？（入れたい場面: 6 まとめの「材料はロボット自身の記録です」のあと）

## 記事との突き合わせで直した所

- 1 持ち込み: 本人の「問題点もたくさんある」を、ハコブくんの「半分は裏付けがあった」のあとに移した（記事の順に合わせた）
- 2 やり取り1: 「安いアームは曲がる範囲が限られる」を「エイイチの机の上のアームは」に直した（記事は mechArm の話）
- 3 やり取り2: 「1センチずれただけで」を「少しずれただけで」にし、1cm・5° は紙の隅に出す形にした（角度を落としていた）。脱線3のひと言も「少しのずれで、崩れる。」に替えた
- 4 山場: 「教えられないことが3つ」を「苦手なことが3つ」にし、立て直しは「教えにくい」に直した（記事は「教えにくく」）
- 5 やり取り3: 大きなモデルが重すぎる理由に「動かすたびに学び直すので、間に合わない」の条件を戻した（追加学習そのものが無理に聞こえないように）
- 5 やり取り3: トースターの例を「動きの出発点を選ばせる方法（DSRL）」と言い、手作り版にあたるのは別の「補正を足す方法（残差強化学習）」だと分けた（取り違えていた）
- 6 まとめ: ナプキンの判定の数字と「基準を決めるのは人」を外し、この回の芯（直す一手間・まねる学習の上に直す層）で締める形に替えた（DAY336「成功の定義」と重なるため）。合わせて、裏を取る所の Dyna の行と、聞きたいことの4問目を差し替えた
```

### 台本のたたき：安いアームを買う前に（LOG375 がもと・考察回_台本たたき.md）

```markdown
# 考察回「安いアームを買う前に」― 台本のたたき（LOG375）

> 【相づち】は、2026-11-02 にエイイチが「採っていい」と了承済み（6本とも）。

共通の決まりは _ネタ帳/考察回_壁打ちの型/考察回_壁打ちの型_台本たたき.md と video_rules.md 10節。

もとの記事: LOG375「協働ロボットを現場に入れる前に ― 法律・資格・院内の調整を調べた」
https://pixelstomotors.com/record/cobot-deployment-law-and-coordination
尺の目安: 約8分　／　柱: ①入れたらどうなる（導入の前に出てくる壁）
既存の動画との分け方: 「事故の責任」（事故のあと誰が責任を負うか）・「協働ロボットはなぜ遅い」（速さと安全の規格）とは重ねない。この回の芯は、**買う・入れる前に出てくる壁（教育・技適・院内の調整）**。ISO 10218・製造物責任・事故の事例は、この回では扱わない（記事に任せる）

## この回の問い（紙に書く縦書きの一文）

安いロボットアームは、買えば使えるのか。

## 数字（1本で3つまで）

| 数字 | 出す場面 | 言い方 |
|---|---|---|
| 70万円台 | 0 つかみ | 「記事を書いた時点で、ミスミの値段では、70万円台から」 |
| 3日間 | 3 特別教育 | 「学科と実技で、3日間」（受講料は記事へ） |
| 4か月 | 5 病院 | 「パナソニックの病院の搬送ロボット HOSPI は、ルートの設定と院内の調整で、最短でも4か月」 |

FR3 と FR5 の値段の差（約5万円）は、数字を言わずに「ほとんど差がなかった」と言う。部署の数も声では言わず、紙に札を並べて見せるだけにする。

## 脱線の場面の候補（4つ）

| 場面 | 画面いっぱいに出すもの（Gemini で作る絵） | ひと言 |
|---|---|---|
| 「届くのは、トラックの荷台の上です」 | 写真風: 配送トラックの荷台の上に、大きな段ボール箱が1つ。荷台の下で、受け取る人が腕を広げて途方に暮れている（顔は見えない後ろ姿） | 受け取りは、荷台の上。 |
| 値段の取り違え（違う国の値段を並べていた） | マンガ（白黒・4コマと同じ絵柄）: 世界地図の上に、同じロボットアームが国ごとに並び、それぞれ違う値札をぶら下げている。地図の前でハコブくんが目を回している | 国が違えば、値段も違う。 |
| 「電源を入れて電波を出すだけで、違反になるおそれ」 | 写真風: 開けた段ボールの中の海外製の配送ロボット。人の指が電源スイッチの数センチ手前で止まっている | スイッチ、待った。 |
| 病院の部署ごとの了承 | マンガ: 病院の廊下で、ハコブくんが6人の担当者（白衣・ナース服・作業着・スーツなど、顔は描き分ける）に囲まれ、1人ずつにおじぎをしている。後ろに長い行列 | 了承、待ち。 |

- 絵に文字を描かせない。値札は白紙で描かせ、動画の側で重ねる（値札に数字は入れない）
- ハコブくんが描いてある絵（2つ目・4つ目）では、左下のハコブくんを消す。参照画像は hakobu_front.png・hakobu_side.png
- 4つ目の「了承」は、実際の病院の手続きの絵ではなく、たとえの絵。字幕かひと言の下に「イメージ」と小さく出す。担当者の人数は、どこかの病院の実際の部署の数として言わない

## 表情の割り当て（主な場面だけ）

| 場面 | ハコブくん | エイイチ |
|---|---|---|
| 「ポチれます」→「荷台の上です」 | ＞▽＜ → 困り眉 | 指さす → のけぞって驚く |
| 「僕も替えが利くので、親近感があります」 | 小さな笑み（照れ） | 半目でツッコむ |
| 「FR5 はお得です」→ 考え中 →「違う国の値段でした」 | ＞▽＜ → 目を閉じる・輪が回る → 困り眉（ボツ） | 首をかしげる → 腕組み |
| 「僕は受けなくていいです。腕がないので」 | 点の目 → 小さな笑み | 吹き出して笑う |
| 「スイッチ、待った」 | 驚き・全身で飛び出す | のけぞって驚く |
| 「では僕が申請してきます」 | ＞▽＜ → 前のめりにコケる（×の目） | 半目でツッコむ |
| 病院の部署の札が次々に貼られる | 涙（実感） → 困り眉 | うなずく |
| 「現場調整力が必須なのかもしれないね」 | 驚き →「それです」 | ひらめく |
| 最後の「部署ごとの了承が要ります」 | ウインク | 吹き出して笑う |

体ごとの動きは3回まで（飛び出す・コケる・涙で揺れる）。どれも全身の絵で動かす。

## 台本

エイイチのセリフの印: 【本人】＝ LOG375 のエイイチの発言を話し言葉に整えたもの（行末に、記事のどの見出しの節の発言かを書いた）。【相づち】＝ Claude の案。本人が採るかを選ぶ（使わないなら消す）。

### 0 つかみ（0:00〜0:30）

ハコブくん：ロボットアームが、通販で買えます。記事を書いた時点で、ミスミの値段では、70万円台からです。
エイイチ【相づち】：ポチれるんだ。
ハコブくん：ポチれます。……ただ、届くのはトラックの荷台の上です。降ろす人と台車は、自分で用意します。
（脱線1: 荷台の上の段ボール。「受け取りは、荷台の上。」→ 紙が戻る）
ハコブくん：そして、荷台から降ろしたあとにも、まだ壁があります。
（紙に問いの縦書き「安いロボットアームは、買えば使えるのか。」）
ハコブくん：今日は答えを伝える回ではありません。エイイチが調べながら考えた途中を、そのまま見せます。

### 1 持ち込み：替えが利くアーム（0:30〜1:40）

ハコブくん：（自己紹介の定型文）
ハコブくん：きっかけは、エイイチが持ってきた、韓国のロボット会社の動画でした。台車にアームを載せて、棚から箱を取る物流ロボットです。
ハコブくん：載っていたアームは、中国の FAIRINO という会社のものでした。
エイイチ【本人】：これ、MicroFactory でも使ってなかった？ 信頼性が高いアームなのかな。（「MicroFactory と PyBrain は、同じ FAIRINO のアームを選んでいた」の節）
ハコブくん：使っていました。アメリカの、机の上に置く箱の中で、小さな電子部品を扱うロボットの会社です。
ハコブくん：ただ、信頼性が高い、とまでは言えません。壊れるまでの平均の時間は、メーカーの資料に載っていませんでした。
ハコブくん（へー）：2社がなぜ選んだのかは、僕の推測です。安くて、必要な性能は十分にあって、壊れたらすぐ買い直せる。差をつけたいのはアームではなく、その上に載せる仕組みのほうだと思います。
エイイチ【本人】：値頃感と、ある程度の信頼性、それに入手のしやすさがポイントみたいだね。（「スタートアップがアームに求めるのは」の節）
ハコブくん（ボケ）：十分に良くて、替えが利く。……僕も替えが利くので、親近感があります。
エイイチ【相づち】：そこ、喜ぶとこ？

### 2 やり取り1：値段の取り違え（1:40〜2:50）

ハコブくん：FAIRINO には、ひと回り小さい FR3 と、大きい FR5 があります。
エイイチ【本人】：FR5 は5キロ持てるのに安いんだ。（「FR3 と FR5 の違いは大きさだけで」の節）
ハコブくん（ボケ）：はい。大きいほうが安い。お得です。
（緑の輪が回る。「ハコブくん 考え中」）
ハコブくん：……すみません。違う国の値段を並べていました。（紙の「お得」に、ボツの判子）
ハコブくん（へー）：同じ店の値段でそろえると、2つの差はほとんどありませんでした。国が違うと、税金と送料と、代理店の取り分が違います。
エイイチ【相づち】：比べるなら、同じ店でそろえないとね。
ハコブくん：はい。違いは、ほぼ大きさだけでした。
エイイチ【本人】：この条件なら、自分も使ってみたいと思うアームかな。選択肢の中に入れておきたい。（「日本ではミスミで FR3 から FR30 まで全機種を買える」の節）
ハコブくん：では、選択肢に入れたとして。ここからが、今日の本題です。

### 3 壁1：特別教育（2:50〜4:00）

エイイチ【本人】：産業用ロボットの安全の特別教育って、いくらくらいかかるの？（「産業用ロボットの特別教育は」の節）
ハコブくん：学科と実技で、3日間です。受講料は、記事に書いてあります。
ハコブくん（へー）：法律で受けさせる義務があるのは、会社が従業員に、ロボットに動きを教える作業や、動かしたままの点検をさせる場合です。
ハコブくん：動く範囲の外で、開始のボタンを押すだけの人は、対象になりません。分かれ目は、アームに直接さわって教える人がいるかどうかです。
エイイチ【本人】：ロボットを納めた先の会社が、誰かに操作させるなら、「特別教育を受ける必要がありますよ」と伝えないといけないね。（「納入先が従業員に操作させるなら」の節）
ハコブくん：はい。受けさせる義務があるのは、使う側の会社です。納める側は、それを伝える側です。
ハコブくん（ボケ）：ちなみに僕は、受けなくていいです。腕がないので。
エイイチ【相づち】：そこは強いんだ。
ハコブくん：腕を付けたら、その腕には同じ決まりがかかります。

### 4 壁2：技適（4:00〜5:20）

ハコブくん：次の壁は、もっと手前にあります。箱を開けて、電源を入れる所です。
ハコブくん：Wi-Fi や無線のリモコンを積んだ海外製のロボットを、自分で輸入したとします。日本の技適マークがないまま電源を入れると、電波を出すだけで、電波法の違反になるおそれがあります。
（脱線3: 電源スイッチの手前で止まる指。「スイッチ、待った。」ハコブくんが驚いて全身で飛び出す → 紙が戻る）
エイイチ【本人】：なるほど。そういうことも含めると、代理店から買ったほうが安全そうだね。（「海外製のロボットは、代理店経由のほうが」の節）
ハコブくん：代理店のほうが、値段は上がります。その分は、確認と保証の代金だと考えられます。
ハコブくん：ただ、代理店が扱っていても、日本向けとは別の海外版が混ざっていることがあります。技適マークは、本体のラベルか仕様書で確かめます。
ハコブくん（へー）：もうひとつ、あとから自分で付けた無線の部品や海外のカメラは、本体とは別の扱いです。
エイイチ【本人】：技適マークの申請には、何が要るの？（「技適は、使う人ではなく」の節）
ハコブくん（ボケ）：では僕が、申請してきます。
（前のめりにコケる。「ドテッ」）
ハコブくん：……技適は、使う人ではなく、作る人か、輸入して売る人が取るものでした。
エイイチ【相づち】：使う側が取るんじゃないんだ。
ハコブくん：はい。申請に要る書類は、回路図と、無線の部分の仕様と……
エイイチ【相づち】：細かいのは記事に書いといて。
ハコブくん：もう書いてあります。（画面の隅に記事のカード）

### 5 山場：病院の廊下（5:20〜6:50）

ハコブくん：教育、電波。ここまでは、アームを1台入れる話でした。ここからは、建物の中で働くロボットの話です。
エイイチ【本人】：ハコブくんみたいに、病院や建物の中で働く搬送ロボットだと、気をつけることは何がある？（「病院の搬送ロボットには」の節）
ハコブくん：……僕の職場の話ですね。
ハコブくん：腕のない搬送ロボットには、決まった資格はありません。その代わり、運ぶ物と建物の決まりがかかります。
ハコブくん：運んでいい薬はどれか。廊下のどこで止まって、どこで充電するか。エレベーターに、どう乗るか。病院の機械に、電波が邪魔をしないか。
（紙に札が1枚ずつ貼られる: 運ぶ薬・廊下と避難の道・エレベーターと扉・電波。ハコブくんが少し涙ぐむ）
ハコブくん：どれも、病院の中の誰かと決めることです。僕の見立てでは、決める相手は1つではなく、部署ごとに分かれていそうです。
（脱線4: 廊下で担当者に1人ずつおじぎをするハコブくん。「了承、待ち。」→ 紙が戻る）
ハコブくん（へー）：パナソニックの病院の搬送ロボット HOSPI は、ルートの設定と院内の調整で、最短でも4か月かかっています。そのうちのどれだけが調整の時間かは、確かめた資料には書いてありませんでした。
エイイチ【本人】：ロボットの専門家になりたいなら、建物の中でどんな調整が要るのか、何が壁になるのか、よく知らないといけないね。（「導入の数か月の大半は」の節）
エイイチ【本人】：フィジカルAIが世の中に浸透していくには、現場調整力が必須なのかもしれないね。（同じ節）
（暗転。縦書きで一文「現場調整力が、必須なのかもしれない。」判子「この見立ては、エイイチから」。エイイチはひらめきの絵）
ハコブくん：……それです。
ハコブくん：ロボットが動けることが増えるほど、決めることも増えていきます。そこは、性能が上がっても、自動では埋まりません。

### 6 まとめ（6:50〜7:30）

（ボードが1枚の表になる。行は「アームの値段」「教育」「電波」「院内の調整」。ボツの判子が押された3つ:「大きいほうがお得」「僕が申請してきます」「替えが利いて親近感」）
ハコブくん：安いアームは、買えます。でも、使う前に決めることは、値段の外にありました。
ハコブくん：誰が教育を受けるか。誰が電波を確かめるか。建物の中で、誰が何を決めるか。調べた範囲では、決まりの多くは使う側の義務で、納める側の仕事は、その義務を果たせる材料をそろえて渡すことでした。
ハコブくん：ちなみに、ボツになった3つは、全部僕が言ったことです。

### 7 残った問い（7:30〜8:00）

ハコブくん：答えは、まだ出ていません。誰が何を決めるかを、入れる前に一覧にして渡せるか。それを確かめるのは、これからです。
ハコブくん：このノートの全文は、サイトの記事にあります。数字の出どころも、ぜんぶそちらに。
ハコブくん：あなたの現場では、ロボットを止められる人は、何人いますか。
エイイチ【相づち】：そういえば、ハコブくんも替えが利くんだっけ。
ハコブくん：……そこは、部署ごとの了承が要ります。

## 裏を取る所（台本を固める前に）

- **部署の6つの札（薬剤部・看護部・施設・情報システム・防火・医療安全と感染対策）と「導入の時間の大半は部署ごとの了承」**: 記事では Claude の答えの整理で、出典の資料にこの並びと「大半」が書いてあるかは確かめていない。HOSPI の FAQ と群馬大学の資料で、どこまで言えるかを確かめる。言えなければ「Claude の整理では」と断るか、「調整に時間がかかる」までに弱める
- 「最短でも4か月」: パナソニックの HOSPI のよくある質問で、言い方（ルートの設定と院内の調整を含むか）を確かめる
- ミスミの「70万円台から」: 公開の直前に商品ページで確かめる。言うときは「記事を書いた時点で」と付ける
- 特別教育の対象の境目（動く範囲の中で教える・動かしたまま点検する人が対象、外でボタンを押すだけは対象外）: 厚生労働省のパンフレットの言い方に合わせる。「受ければ安全」「受ければ使ってよい」に聞こえないようにする（video_rules 2節22）
- 技適: 「電源を入れて電波を出すだけで、違反になるおそれ」は総務省の外国製無線機のページの言い方に合わせる。180日の実験の特例は声で言わない（記事へ）。「違反になるのはあとから付けた部品が多い」は記事でも根拠の出典がない Claude の言葉なので、言うなら「そういう例がある」に弱めるか、外す
- 「技適は作る人か輸入して売る人が取る」: 総務省・MONOist の資料で言い方を確かめる（使う人が自分で取る道が全くないかどうか）
- 「腕のない搬送ロボットには、決まった資格はない」: 記事の言い方（使う人にも納める人にも必須の資格はない）の範囲で言う
- FR3 と FR5 の差がほとんどない: 同じ店（ドイツの販売店）の値段での比べ方。日本のミスミの表でも差が小さいことを確かめる

## エイイチに聞きたいこと（答えがあれば入れたい場面）

1. FAIRINO は、いまも「選択肢の中に入れておきたい」アームですか。代理店経由・教育・置き場所まで知ったうえで、買う・買わないの気持ちは変わりましたか。（2 の終わりと 6 のまとめ。山場の「自分なら買うか」をここで本人の言葉にしたい）
2. Claude が違う国の値段を並べていたと分かったとき、どう思いましたか。（2 のボツの直後）
3. 「現場調整力」と言ったとき、頭にあった具体的な場面はありますか。アパレルの量産や、GIG のディレクションで、部署ごとの了承を取って回した経験と近いと感じますか。（5 の山場の見立ての直後。記事ではこの比較は Claude の言葉なので、本人の言葉があれば差し替える）
4. 産業用ロボットの特別教育は、自分でも受けるつもりがありますか。（3 の終わり）
5. 最後の「あなたの現場では、ロボットを止められる人は何人いますか」は、見る人への問いとして合っていますか。別の問いの方がよければ教えてください。（7）

## 記事との突き合わせで直した所

- 1 持ち込み「机の上で部品を組むロボットの会社」→ 記事の範囲の「机の上に置く箱の中で、小さな電子部品を扱うロボットの会社」に直した
- 1 持ち込み「2社が選んだ理由は」→ 記事では Claude の推測（「どちらも同じ形だと思います」）なので、「僕の推測です」「〜だと思います」と言う形にした
- 4 技適「海外製のロボットを輸入して」→ 記事の条件「Wi-Fi や無線のリモコンを積んでいる機器は」を戻した
- 4 技適 代理店の話に、記事の但し書き「日本向けとは別の海外版が混ざっていることがある。本体のラベルか仕様書で確かめる」を戻した（「代理店なら大丈夫」に聞こえないように）
- 4 技適「違反になるのは、そこが多いそうです」→ 出典のない Claude の言葉なので外し、「本体とは別の扱い」までにした
- 5 山場 部署6つの札と「どの部署にも止める権限がある」→ 出典のない Claude の整理なので、札を記事の決まりの4つ（運ぶ薬・廊下と避難の道・エレベーターと扉・電波）に替え、「部署ごとに分かれていそう」と見立てとして言う形にした
- 5 山場 HOSPI の4か月に「そのうちのどれだけが調整の時間かは、確かめた資料には書いてない」を足した（「導入の時間の大半は部署ごとの了承」と言い切らないため）
- 5 脱線4 の注記に「担当者の人数を、実際の部署の数として言わない」を足した
- 6 まとめ「決まりの多くは使う側の義務」に「調べた範囲では」を付けた
```

### 記事との突き合わせの指摘：現場で扱えるか・照明で崩れるピッキング・成功の定義（別のエージェントの報告）

```markdown
3本とも記事と1文ずつ突き合わせました。直すべき点が一番多いのは3本目（DAY336）で、【本人】の行を変えたために事実と食い違っている所があります。

## 1. 現場で扱えるか ↔ LOG389

**A. 食い違い**
- 128「それが壁だそうです」：記事では、事業本部長がボトルネックとしているのは「現場に運用改善を続ける担い手がいないこと」です（記事228行）。充電切れや紙パックは、人の作業に戻ってしまう例として出ているだけです。
- 99 の判子「この見立ては、エイイチから」：「性能より扱えるUX」も、3つの問い（戻せるか など）も Claude の答えです（記事103・114〜120行）。エイイチは引用して「そうなんだよな」と同意しただけです。

**B. 根拠のない事実**
- 105「デモの映像は、うまくいった回だからです」：記事にあるのは「技術デモでは、この部分はほぼ評価されません」（122行）だけで、理由は書かれていません。
- 127「会社の発表では」：記事は「だそうです」と書くだけで、出どころが会社の発表だとは書いていません。

**C. 言い過ぎ**
- 131「ロボットの壁は、紙パックでした」：上のAの1点目と同じ理由で、記事の言うボトルネック（担い手がいない）とずれます。
- 73「議論で多かったのは〜という声」：記事が紹介している投稿者は3人で、そのうち2人の意見です。「多かった」とまでは言えません。
- 147 のまとめの一文「止まったとき、店の人が自分で戻せるか」：記事の結論は「その人が自分で扱えるように、作業と店の作りを切り直せるか」（411行）です。「切り直し」が落ちています。
- 141「新しい店を建てるときに」：記事は「新店や改装のタイミング」（363行）で、改装が落ちています。

**D. 【本人】の行**
- 82 の前半「失敗が許せて、繰り返しの多い作業から」：Claude の文をエイイチが引用した部分です（記事58・65行）。本人の言葉は「そうだね。データも取りやすいし…」からです。

## 2. 照明で崩れるピッキング ↔ LOG412

**A. 食い違い**
- 143「カメラの載せやすさ」：記事の表は「センサーの載せやすさ」（273行）です。

**B. 根拠のない事実**
- 122「ロボットのカメラは、付けた所から動きません」：記事は人の目を「固定カメラとは別物」と比べているだけです（174行）。ロボットのカメラ全般が動かないとは書いていません。

**C. 言い過ぎ**
- 61〜62「原因は、電気でした」「照明が変わっただけです」：照明が原因というのは、発表した人たちの説明です（記事15行）。台本ではそれを事実として言い切っています。
- 109「やり直しを含めて8〜9割」：記事の前提「動作範囲を決め、その中で」（116行）が落ちています。
- 145：記事の但し書き「ただ境界は少しずつ動いています」（293行）が落ちています。

**D. 【本人】の行**
- 88「照明を学ばせるのか」：本人の言葉は「環境条件学ばせるのか」（77行）です。軽い言い換えなので、これ以外は「なし」です。

## 3. 成功の定義 ↔ DAY336

**A. 食い違い**
- 63〜65：本人の言葉は「なんだこの**シミュレーション**」（記事27行）です。台本はこれを「なんだこれ」に変え、そのうえで「全部シミュレーションです」「え、全部？」とやり取りさせています。エイイチは最初からシミュレーションと言っているので、記事と食い違います（D にも当たります）。
- 66「本物の腕は、まだ一度もこの板を組んでいません」：記事には、同じチームの SGS で UR5e が実機のボードを組み立てる映像があると書かれています（129行）。裏を取る欄で指摘済みですが、本文の行は直っていません。
- 61「教わったことは、1つだけです。『組み上がったら、1点』」：記事の訂正（56・66行）では、報酬に罰則も入っています。この行はボケの印なしで事実として言っています。
- 75「NIST は…板です」：NIST は米国国立標準技術研究所で、板は「NIST の組立ボード」です（14行）。
- 112「並べる腕の数を増やすと」：記事が増やしているのは並列数（シミュレーションの環境の数）です（80・100行）。

**B. 根拠のない事実**
- 109「途中を褒めると、褒められる所で止まってしまうようです」：記事には17.8%に落ちた理由が書かれていません。

**C. 言い過ぎ**
- 127〜128：滑らかさを区切りがないことだけで説明しています。記事の但し書き「土台の効果も大きい…機体と制御の掛け算」（167行）と、「と思います」という含みが落ちています。
- 107「17.8%まで落ちました」：これは20種類を1本で学ぶ条件の値です。組立ごとに学ぶ条件では78.3%（記事97行）という区別が落ちています。
- 141「いきなり全部は、だれも解けないからです」：記事は「普通はなかなか成功に届きません」（47行）までしか言っていません。

**D. 【本人】の行**
- 144 の判子「この見立ては、エイイチから」と一文「動きではなく、成功を書く」：「成功の定義を決める仕事が増える」は Claude の答えです（記事148〜152行）。
- 143「向いてる」：本人の言葉は「向いていそうだな」（247行）で、含みが消えています。
- 63：上の A の1点目と同じです。
```

### 記事との突き合わせの指摘：どこまでいじっていい・人のお手本の先へ・安いアームを買う前に（別のエージェントの報告）

```markdown
台本3本と記事を、全文1文ずつ突き合わせました。直すべきものが特に多いのは2か所です。1本目の判子「この見立ては、エイイチから」が Claude の見立てに押されていること、3本目の技適で、記事にある但し書きが落ちていることです。

## 1. どこまでいじっていい ↔ LOG406

**A. 食い違い**
- 115行「改造は、ネジから、お手本へ。」に判子「この見立ては、エイイチから」：この一文は Claude の見立てです（記事の冒頭「というのが今の考えです」、H の節「改造はネジやコードではなく、データと追加学習になります」）。エイイチが言ったのは「Hにはかなり魅力がありそう」だけです。
- 123行「中国の人型ロボットのメーカー Unitree」：記事では「ヒューマノイド・四足ロボット」のメーカーです。計算機が2つに分かれる話は G1 の手引きによるもので、台本の「裏を取る所」にもそう書いてあります。

**B. 根拠のない事実**：なし（97行「運ぶ物によっては、その間ずっと心配」は感想で、事実は言っていません）

**C. 言い過ぎ**
- 54行「事故が起きたら…改造した人、だそうです」：法律の責任を一般化しています。記事の条件は、EU の決まりなら「メーカーが想定していない改変で危険を増やした場合」、日本の製造物責任法なら「業として加工した者」です。メーカーの責任を問いにくくなる、という点も記事は「ここは分析」と断っています。
- 55行「車なら、買えば改造できます」：記事では「思いがち」とされている考えです。実際には、保安基準に合わなくなる改造は禁止され、罰則もあります（「2. 法律は持ち主かどうかに関係なく効く」の節）。
- 128行「機体は安くなっていきます。値打ちが残るのは…」：記事では Claude の見立てです（「〜近くなると思います」の流れ）。ハコブくんが事実として言い切っています。

**D. 【本人】**
- 114行「追加学習で、自分の店専用の動きをつくる。これにはかなり魅力がありそう」：元の発言は「Hにはかなり魅力がありそう」です。前半は Claude が付けた H の見出しの言葉なので、本人の言葉にしてよいかを本人に確かめてください。
- 76行：記事の「認められない」が「できない」に変わっています。小さな違いです。

## 2. 人のお手本の先へ ↔ LOG392

**A. 食い違い**
- 135行「つかむ位置のずれを…この小さな部品を手作りしたもの」：直前のトースターの例（①DSRL）を指すように聞こえます。記事が手作り版にあたるとしているのは②残差強化学習です（「②の考え方は、すでに使っています」）。
- 69〜70行の順番：記事では、Claude が「半分は裏付けがある」と答えたあとに、エイイチが「問題点もたくさん」と言っています。台本では、本人の発言のあとに「調べたら」が来ます。

**B. 根拠のない事実**：なし

**C. 言い過ぎ**
- 104行「1センチずれただけで、98%から64%」：記事は「1cm・5°ずれただけで」です。角度が落ちています（台本の「裏を取る所」も気づいていますが、未決のままです）。
- 113〜114行「お手本では、教えられないことが3つ」：記事のまとめでは、立て直しは「教えにくく」です。3つとも「教えられない」になっています。
- 127行「π0.5…を丸ごと学び直すのは重すぎます」：記事では「強化学習は1回動かすたびに学び直すので、この重さでは間に合わない」という条件付きの話です。この条件が落ちているので、追加学習そのものが無理に聞こえます。
- 79行「安いアームは曲がる範囲が限られています」：記事が言っているのは mechArm のことで、安いアーム一般の話ではありません。

**D. 【本人】**：なし

## 3. 安いアームを買う前に ↔ LOG375

**A. 食い違い**：なし

**B. 根拠のない事実**
- 73行「机の上で部品を組むロボットの会社」：記事は「卓上ロボットセルの会社」「小さな電子部品を扱います」までです。「組む」という言い方は記事にありません。

**C. 言い過ぎ**
- 111行：代理店経由の話から、記事の但し書き「代理店が扱っていても、日本向けとは別の海外版が混ざっていることがある。本体のラベルか仕様書で確認」が落ちています。このままでは「代理店なら大丈夫」に聞こえます。
- 108行「海外製のロボットを…電源を入れると…違反になるおそれ」：記事の条件「Wi-Fi や無線のリモコンを積んでいる機器は」が落ちています。
- 75行「2社が選んだ理由は…ことでした」：記事では Claude の推測です（「どちらも同じ形だと思います」）。言い切りになっています。
- 112行「違反になるのは、そこが多いそうです」：記事でも出典のない Claude の言葉です。台本の「裏を取る所」で弱めるか外すとしていますが、本文は直っていません。

**D. 【本人】**：なし（72・76・83・90・95・99・110・113・125・133・134行は、どれも記事の引用の範囲に収まっています）
```

### narration.py（2本目の台本の1文ずつと、読みの直し・作り手の声で読む文）

```python
# -*- coding: utf-8 -*-
# 台本「ロボットが店に広がるかを決めるのは、賢さか」— 考察回「壁打ちの型」の2本目（もとは LOG389）
#   2026-11-02 1版。もとの台本: 同じフォルダの 考察回_台本たたき.md（別のエージェントが記事と1文ずつ照合して直した版）
#   書き写した元: 動画/頭脳は脳のように分かれる/narration.py（形・読みの直し・自己紹介とアウトロの定型・EI_LINES）
#   codex はかけない（エイイチの指示 2026-11-02）。相づちはエイイチが「採っていい」と了承（2026-11-02）
#   エイイチのセリフ: LOG389 の本人の言葉を話し言葉に整えたもの＋本人に聞いた答え2つ（first_ei・rest_ei2）＋見立て帳1つ（who_ei の3文目）
#     「店舗のおばちゃんたち」は本人の指示で「店のスタッフさん」に言い換えた
#   出典（台本の中の事実）:
#     - 成功率99%・毎時600回・毎時6回: LOG389 の中の、X の議論（HM の指摘）をもとにした例の計算。画面の札に「例の計算」と出す
#     - 7000社以上・2万5000台以上・事業本部長の発言・JILBY の自動充電と紙パック: マイナビニュース（2026-06-29）https://news.mynavi.jp/article/newsinsight-463/
#       （発言の原文「充電が切れたり、紙パックがすぐに一杯になったりという些細なことで、すぐに人の作業に戻ってしまう」「継続的に運用改善に取り組む人材がいない」）
#     - 調理場と客席の区画・形は自治体や保健所の判断: 食品衛生法の施設基準（例: 那覇市・北九州市の基準）
# 話すのはハコブくん。エイイチの文は EI_LINES（槙原の声）
#
# 各要素: (場面の名前, 表情, 字幕の文, 後ろの間[秒])  間を省略すると 0.35 秒
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")

SEGS = [
 # 0 つかみ（問いの縦書き）
 ("hook_num", "base", "仮に、成功率99%。ロボットとしては、かなり優秀です。"),
 ("hook_num", "base", "でも、1時間に600回働くと、1時間に6回、人が駆けつけることになります。", 0.6),
 ("hook_num", "surprise", "店の人からすると、10分に1回、呼ばれるロボットです。", 0.8),
 ("hook_ei", "base", "それ、優秀なのかな。", 0.6),
 ("hook_reply", "trouble", "……僕も、自信がなくなってきました。", 1.2),
 ("hook_q", "base", "今日は、答えを伝える回ではありません。エイイチが考えている途中を、そのまま見せます。", 1.8),
 # 1 自己紹介
 ("title", "smile", "Pixels to Motors。案内役のハコブくんです。"),
 ("title", "base", "この番組では、フィジカルAIのニュースや実機の記録から、現場で使える形を考えます。", 1.2),
 ("title_eiichi", "base", "エイイチは、本業のデザイナーをしながら、ロボティクスの研究と開発をしています。｜その中で分かったことと、そこから考えた見立てを、ハコブくんがお伝えします。", 1.2),
 ("title_kabe", "smile", "今回は、エイイチの壁打ちに、ハコブくんが付き合います。", 1.8),
 # 2 持ち込み（脱線①・ボタン1回目）
 ("bring", "base", "エイイチが持ち込んだのは、海外のロボットやAIの人たちの、Xの議論でした。"),
 ("bring", "base", "お題は、ロボットにも、ChatGPTのように、一夜で世の中が変わる瞬間は来るのか。", 0.6),
 ("bring_ei", "base", "実際どうなんだろうね。", 0.6),
 ("morning", "joy", "来ます。明日の朝、僕にも来ます。起きたら、なんでもできるようになっています。", 1.5),
 ("bring2", "base", "議論には、できるようになる瞬間は来ても、広がるには時間がかかる、という声がありました。"),
 ("bring2", "base", "ChatGPTは、ブラウザを開けば試せました。間違った答えが出ても、読み流せば済みます。"),
 ("bring2", "base", "ロボットは、置く場所を空けて、止まったときの対処を決めて、店のやり方を変えないと使えません。", 1.5),
 ("button1", "smile", "……失礼しました。今のが、止まったときの対処です。", 1.8),
 # 3 やり取り1：なぜ配膳ロボットが先に広がったか（脱線③・コケる）
 ("why", "base", "では、どんな仕事から広がるのか。失敗が許せて、繰り返しの多い作業から、だと考えました。", 0.6),
 ("why_ei", "base", "そうだね。データも取りやすいし、入れるハードルも低いし、お金もかからないからね。", 0.4),
 ("why_ei", "base", "サービスロボットが広がり始めたのも、このあたりが関係してるね。", 0.6),
 ("why", "base", "ファミレスの配膳ロボットは、その条件が全部そろっていました。", 0.5),
 ("first_ei", "base", "初めて店で見たときは、とうとうロボットが店舗に入った！って感激したのを覚えてる。", 0.6),
 ("first", "joy", "……感激していただいて、ありがとうございます。同じロボットとして。", 1.0),
 ("cond", "base", "止まっても、料理が少し遅れるだけ。毎日、何百回も往復する。そして、ホールの人が集まらない。", 0.8),
 ("last", "surprise", "しかも、一番難しい所を、ロボットにやらせていません。"),
 ("last", "base", "料理をテーブルに置くのはお客さん。トレーに載せるのは店員さんです。", 0.6),
 ("last_boke", "joy", "では僕が、料理もテーブルに置きます。最後まで、責任を持って。", 1.5),
 ("last_ei", "base", "だから人に任せたんだよ。", 0.5),
 ("last2", "trouble", "……はい。配膳ロボットは、頑張らない所を決めて、広がりました。", 1.8),
 # 4 山場：扱えるか
 ("easy", "base", "もう1つ、配膳ロボットには強みがあります。"),
 ("easy", "base", "使い方は、テーブル番号のボタンを押すだけ。止まったら、どかせばいい。", 0.5),
 ("easy_ei", "base", "店のスタッフさんでも使えてるしね。ポイント高いよね。", 0.6),
 ("easy", "base", "研修もマニュアルも、ほとんどいりません。入れたあとに、エンジニアを呼ぶ手間が、ほぼ消えました。"),
 ("easy", "think", "裏を返すと、どんなに賢いロボットでも、｜止まったときにどうすればいいか｜分からなければ、広がりません。", 0.6),
 ("peak_ei", "base", "そうなんだよな。そこをしっかり見極めないと、どんなに素晴らしい技術のロボットでも、広がらないよね。", 1.5),
 ("q3", "base", "見極めは、3つの問いに分けられます。", 0.5),
 ("q3", "base", "1つ目。止まったとき、理由が分かるか。通れません、なのか、物を見失いました、なのか。"),
 ("q3", "base", "2つ目。エンジニアを呼ばずに、その場の人が戻せるか。"),
 ("q3", "trouble", "3つ目。次にどう動くか、周りの人に読めるか。読めないと、怖いです。", 0.8),
 ("demo", "surprise", "この3つは、技術のデモでは、ほとんど評価されません。", 0.5),
 ("demo_ei", "base", "デモの点数には、入らないんだね。", 0.5),
 ("demo", "wink", "はい。僕も、さっきコケた所は、点数に入れないでほしいです。", 0.4),
 ("demo_ei2", "base", "入れとくよ。", 1.8),
 # 5 やり取り2：足りなくなるのは誰か（ボタン2回目）
 ("who", "base", "話を、店の外に広げます。配膳や清掃のように、動き回る仕事のロボットは、機体が安くなってきました。", 0.6),
 ("who_ei", "base", "移動系はほんとうに早そうだし、コストも一気に安くなりそうだよね。", 0.3),
 ("who_ei", "base", "その分、入れるための営業やエンジニアが、足りなくなりそうだよね。", 0.4),
 ("who_ei", "base", "ロボットで利益が残るのは、作る側より、入れて回す側だと思う。", 0.8),
 ("who", "base", "足りなくなるのは、店の通路の幅や段差を見て、どこまでをロボットに任せるか線を引き、止まったときの対処を、店のルールにする人です。", 1.5),
 ("button2", "smile", "……ありがとうございます。今みたいに戻してくれる人が、足りないんです。", 0.8),
 ("local_ei", "base", "でも、サービスロボットを入れるのは、地方の方が切実なんだよね。この問題をどう解決できるかが、鍵だね。", 0.4),
 ("local_ei", "base", "家電量販店とか電気屋さんが、候補には上がりそうだけど、実際どうなんだろう？", 0.6),
 ("local", "base", "町の電気屋さんは、何かあればすぐ来てくれる関係を、もう持っています。止まったときの駆けつけに、向いています。"),
 ("local", "think", "ただ、どこまでロボットに任せるかを、店と一緒に決める力は、どちらにもまだありません。そこは、離れた所から専門の人が受け持つ形が、現実的だと考えました。", 0.5),
 ("local_ei2", "base", "役割を分けるんだね。", 1.8),
 # 6 やり取り3：止まらない作りと、扉（飛び出す・脱線④）
 ("iris_ei", "base", "アイリスオーヤマが、ロボットを扱ってなかったっけ？ どうしてるか、調べてみて。", 0.6),
 ("iris", "base", "調べました。報道では、これまでに7000社以上に、2万5000台以上を入れているそうです。"),
 ("iris", "trouble", "事業の責任者は、充電が切れたり、｜紙パックがすぐいっぱいになったりする｜小さなことで、｜すぐ人の作業に戻ってしまう、と話しています。"),
 ("iris", "base", "そして、運用を直し続ける人が現場にいないことが、広める上での壁だ、と。", 0.6),
 ("iris", "base", "なので、新しい清掃ロボは、掃除が終わると自分で充電に戻り、紙パックも替えやすくしました。", 1.2),
 ("iris", "joy", "……紙パックです。直し続ける人がいないなら、紙パックで人を呼ばない作りにする。", 0.6),
 ("iris_ei2", "base", "家電の会社らしいね。", 1.0),
 ("door", "base", "残る壁は、下げ膳です。食べ終わったお皿を、洗い場まで運ぶ仕事です。", 0.5),
 ("door_ei", "base", "ロボットがお店のフロントからバックヤードに行くには、扉を開けられないといけない。ここが今、目に見える問題かな。", 1.5),
 ("door_boke", "joy", "大丈夫です。扉は、体当たりで開けます。", 1.2),
 ("door", "base", "決まりで求められているのは、調理場を客席と仕切ることです。どう仕切るかは、地域の決まりや保健所の判断で変わります。"),
 ("door", "base", "なので、扉を通らない手があります。両側から取り出せる棚を客席側に置いて、ロボットはそこにトレーを置くだけにする。", 0.6),
 ("door_ei2", "base", "そうだね、現場設計だね。正直、直接洗い場までロボットが持って行けたら、最高だけどね。", 0.6),
 ("door", "base", "それは、新しい店や改装のときに、ロボットの通り道ごと設計する所から、だと考えました。", 1.8),
 # 7 まとめ（ボードが表になる）
 ("sum", "smile", "ここまでを、1枚にまとめます。", 0.5),
 ("sum", "base", "残っている壁の多くは、ロボットの賢さではありませんでした。店の作りと、仕事の分け方と、保健所との調整です。", 0.6),
 ("sum", "base", "決めていたのは、店の人が自分で扱えるように、作業と店の作りを切り直せるか。", 1.0),
 ("sum", "wink", "ちなみに、ボツになった3つは、全部、僕が自分でやろうとしたことです。", 0.5),
 ("sum_ei", "base", "全部やらなくていいんだよ。", 1.8),
 # 8 残った問い（ボタン3回目・自分で押す）
 ("rest_ei", "base", "この辺の問題を解決する力を持つ人が、フィジカルAIの時代には、重宝されそうだね。", 0.6),
 ("rest", "base", "店とロボットのあいだに立って、止まらない店に切り直す役です。ただ、その役には、まだ名前も、求人の枠もありません。", 0.5),
 ("rest", "base", "エイイチなら、どんな店から始めますか。", 0.4),
 ("rest_ei2", "base", "大型のお店から、スタートしたいね。", 0.6),
 ("rest", "base", "誰が最初にやるのかは、まだ分かりません。"),
 ("rest", "base", "この考察ノートの全文は、サイトの記事にあります。調べた決まりと数字の出どころは、概要欄に置いてあります。", 0.8),
 ("ask", "base", "あなたの店でロボットが止まったら、誰が戻しますか。", 1.5),
 ("end", "joy", "自分で戻りました。", 0.5),
 ("end_ei", "base", "それが一番えらい。", 1.8),
 # 9 アウトロ
 ("outro", "smile", "この動画が役に立ったら、高評価とチャンネル登録をお願いします。"),
 ("outro", "base", "ロボットの開発や導入の相談は、概要欄の連絡先から、エイイチに直接どうぞ。"),
 ("outro", "wink", "コメントは、エイイチが全部読んでいます。それではまた。", 1.8),
]

# エイイチの声で読む文（槙原の声を流用・video_rules.md 1-4）。場面の名前が _ei か _ei2 で終わる文
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith(("_ei", "_ei2"))]

# 「エイイチ」を残す文（自己紹介・アウトロのほかに名前が要る文）。文の頭で探す（video_rules.md 3-1）
NAME_OK = [i + 1 for i, seg in enumerate(SEGS) if seg[2].startswith((
    "今日は、答えを伝える回では", "今回は、エイイチの壁打ちに", "エイイチが持ち込んだのは",
    "エイイチなら、どんな店から"))]

READ = [
 ("Pixels to Motors", "ピクセルズ トゥー モーターズ"), ("ChatGPT", "チャットジーピーティー"), ("Xの", "エックスの"),
 ("フィジカルAI", "フィジカルエーアイ"), ("AI", "エーアイ"), ("99%", "きゅうじゅうきゅうパーセント"),
 ("600回", "ろっぴゃっかい"), ("6回", "ろっかい"), ("1時間", "いちじかん"), ("10分", "じゅっぷん"), ("1回", "いっかい"),
 ("7000社", "ななせんしゃ"), ("2万5000台", "にまんごせんだい"), ("3つ", "みっつ"), ("1つ目", "ひとつめ"), ("2つ目", "ふたつめ"),
 ("3つ目", "みっつめ"), ("1つ", "ひとつ"), ("1枚", "いちまい"),
 ("栄一", "えいいち"), ("「", ""), ("」", ""), ("｜", ""), ("…", ""),
]

ELEVEN_READ = [
    ('エイイチ', '栄一'),   # video_rules.md 3-1
    ('ChatGPT', 'チャットジーピーティー'),
    ('Xの', 'エックスの'),
    ('99%', '99パーセント'),
    # この回で先回りして足す読み（全文を聞いて確かめる）
    ('下げ膳', 'さげぜん'),
    ('7000社', '七千社'),
    ('2万5000台', '二万五千台'),
    ('600回', '六百回'),
    ('何百回', 'なんびゃっかい'),
    ('10分', 'じゅっぷん'),
    ('通り道', 'とおりみち'),
    ('一番', 'いちばん'),
    ('入れないで', 'いれないで'),   # 2026-11-02 エイイチの指摘（「はいれない」と読んでいた）
]

OVERRIDE = {}

def reading(t):
    t = OVERRIDE.get(t, t)
    for a, b in READ:
        t = t.replace(a, b)
    return t


def parse(seg):
    """1行を (場面, 表情, 字幕, 間) にそろえる"""
    if len(seg) >= 3 and seg[1] in FACES:
        scene, face, text = seg[0], seg[1], seg[2]
        pause = seg[3] if len(seg) > 3 else 0.35
    else:
        scene, face, text = seg[0], "base", seg[1]
        pause = seg[2] if len(seg) > 2 else 0.35
    return scene, face, text, pause
```

### scenes_kabe.py（2本目 v3 の紙の場面・脱線・ボタン・表情と動き・効果音）

```python
# -*- coding: utf-8 -*-
# 動画「ロボットが店に広がるかを決めるのは、賢さか」— 考察回「壁打ちの型」の2本目（もとは LOG389）の場面
# 書き写した元: 頭脳は脳のように分かれる/scenes_kabe.py（型の決まりは video_rules.md 10節）
#   紙の文字は真ん中にそろえる／線を使わず面で分ける（事実＝墨・エイイチの見立て＝濃い灰・ハコブくん＝薄い灰）
#   朱は判子とリアクション（ボツ・入れとく・この見立ては、エイイチから）だけ／字幕は動かさない
#   脱線（画面いっぱいの絵）は4回: 1時間に6回（マンガ）・朝の街（写真風）・最後の動作（マンガ）・扉（マンガ）。どれも Gemini で作った絵
#   天丼: ハコブくんが固まると、頭の上に「再開」のボタンが出る。エイイチが押す（2回）。最後だけハコブくんが自分で押す
import os
from kabe_kit import *
import scene_kit as _sk

_tl = Timeline()
tl = _tl
N = len(_tl.idx)
A = lambda i, off=0.0: tl.start(i) + off          # 動画の頭からの秒
S = tl.speech                                      # その文を読み終わるまでの長さ
LOGO = _sk.LOGO
BRAND = f'<img src="{LOGO}" style="position:absolute;right:56px;top:40px;height:30px;filter:invert(1);opacity:.55">'
SANS = "font-family:'Noto Sans CJK JP',sans-serif;"
BG = "src/bg/"
GEM = "絵は生成AI（Gemini）で作成"

BLOCKS = []


def block(name, sents, fn, video=None):
    b0 = _tl.start(sents[0])
    T = lambda i, off=0.0: tl.start(i) - b0 + off
    E = lambda i: tl.end(i) - b0
    b = dict(name=name, sents=list(sents))
    if video:
        b["video"] = video
    else:
        b["html"] = page(fn(T, E) + BRAND)
    BLOCKS.append(b)


def inkl(text, t, step=0.05):
    """「／」で行を分けて書く（1〜2文字だけ次の行に落ちないように）"""
    out, tt = [], t
    for k, part in enumerate(text.split("／")):
        out.append(ink(part, tt, step)); tt += len(part) * step
    return "<br>".join(out)


def line(text, t, size=30, weight=700, step=0.05, style=""):
    return f'<div style="{SANS}font-size:{size}px;font-weight:{weight};{style}">{ink(text, t, step)}</div>'


def qline(text, t, size=46, step=0.06, style=""):
    return f'<div class="serif" style="font-size:{size}px;font-weight:700;line-height:1.5;{style}">{ink(text, t, step)}</div>'


def src(text, t=0.0):
    return f'<div class="src" style="opacity:0;animation:show .01s linear {t:.3f}s forwards">{text}</div>'


BTN_CSS = """<style>
.btn { position:absolute; left:96px; top:440px; width:190px; height:110px; border-radius:22px; background:#f5f3ee; border:6px solid #141311;
       box-shadow:0 10px 0 #141311; font-family:'Noto Sans CJK JP',sans-serif; font-weight:900; font-size:40px; color:#141311;
       display:flex; align-items:center; justify-content:center; opacity:0; z-index:5; }
.btn small { position:absolute; top:-40px; left:0; right:0; text-align:center; font-size:22px; font-weight:700; color:#f5f3ee; letter-spacing:.1em; }
@keyframes press { 0% { transform:none; box-shadow:0 10px 0 #141311; } 50% { transform:translateY(10px); box-shadow:0 0 0 #141311; background:#c4472a; color:#fff; } 100% { transform:none; box-shadow:0 10px 0 #141311; } }
</style>"""


def btn(t_show, t_press, t_hide, who="エイイチが押す"):
    """ハコブくんの頭の上の「再開」ボタン（天丼）"""
    return (BTN_CSS + f'<div class="btn" style="animation:pop .3s ease-out {t_show:.3f}s forwards, press .35s ease-out {t_press:.3f}s, '
            f'hide .2s linear {t_hide:.3f}s forwards"><small>{who}</small>再開</div>'
            + f'<div class="big" style="left:60px;right:auto;top:300px;font-size:80px;transform:rotate(-6deg);z-index:6"><span style="animation:boom .3s cubic-bezier(.2,1.8,.4,1) {t_press:.3f}s forwards, hide .2s linear {t_hide:.3f}s forwards">ピッ</span></div>')


# ================= 0 つかみ =================
def hook(T, E):
    fly = (T(2, 0.1), T(3, 0.15))
    return (dassen(BG + "1時間に6回.jpg", fly[0] + 0.05, fly[1] - 0.05, words="!1時間に|6回。", word_style="top:120px;font-size:130px", src_note=GEM)
            + paper(tag("考察ノート") + '<div class="center" style="gap:6px">'
                    + line("仮に、成功率", T(0, 0.2), size=34, weight=500)
                    + f'<div class="num" style="font-size:230px;line-height:1.05"><span id="c99">0</span><span style="font-size:110px">%</span></div>'
                    + f'<div class="serif" style="font-size:44px;font-weight:700;margin-top:10px">{ink("1時間に600回働くと、", T(1, 0.3), 0.06)}</div>'
                    + f'<div class="serif" style="font-size:44px;font-weight:700">{land("6回", T(1, 3.0), "font-size:120px;font-weight:900")}{ink("人が駆けつける", T(1, 3.5), 0.07)}</div>'
                    + '</div>' + src("例の計算（X の議論の指摘をもとに）", T(0, 0.5)), 0.0, flights=[fly])
            + stamp("優秀？", T(3, 0.3), "right:380px;top:560px;font-size:64px")
            + shake_js([(T(3, 0.65), 0.3)])
            + counter_js("c99", T(0, 1.0), T(0, 2.6), 99, dec=0))
block("hook", [0, 1, 2, 3, 4], hook)


def hook_q(T, E):
    return paper(tag("考察回　壁打ち") +
                 '<div class="center"><p class="v serif" style="font-size:54px;line-height:1.6;font-weight:300;letter-spacing:.06em;">'
                 f'<span data-ink="{T(5, 0.3):.2f},0.09" style="font-size:66px;font-weight:700;">ロボットが</span><br>'
                 f'<span data-ink="{T(5, 0.9):.2f},0.09">店に広がるかを</span><br>'
                 f'<span data-ink="{T(5, 1.6):.2f},0.09">決めるのは、</span><br>'
                 f'{land("賢さ", T(5, 2.4), "font-size:104px;font-weight:900")}<span data-ink="{T(5, 2.9):.2f},0.09">か。</span></p></div>', 0.0)
block("hook_q", [5], hook_q)

# ================= 1 自己紹介（DAY124 の映像とテロップ） =================
O_TITLE = '<div class="lt"><img class="a" src="' + LOGO + '"><div class="b">フィジカルAI解説</div><div class="c">案内役：ハコブくん（AI音声）</div></div>'
O_EIICHI = '<div class="lt"><img class="a" src="' + LOGO + '"><div class="b">エイイチ</div><div class="c">デザイナー／ロボティクスの研究・開発</div></div>'
O_OUTRO = '<div class="lt"><img class="a" src="' + LOGO + '"><div class="b">相談は概要欄の連絡先から</div><div class="c">高評価・チャンネル登録／コメントはエイイチが全部読んでいます</div></div>'
OVERLAYS = {"title": _sk.overlay(O_TITLE), "title_eiichi": _sk.overlay(O_EIICHI), "outro": _sk.overlay(O_OUTRO)}
_t_title = tl.end(7) - tl.start(6)
block("title", [6, 7], None, video=("src/day124_crop.mp4", 4.5, "png/ovl/title.png"))
block("title_eiichi", [8], None, video=("src/day124_crop.mp4", 4.5 + _t_title, "png/ovl/title_eiichi.png"))


def title_kabe(T, E):
    return paper(tag("考察回") + '<div class="center" style="gap:30px">'
                 + f'<div class="serif" style="font-size:150px;font-weight:900;line-height:1.1">{land("壁打ち", T(9, 0.5))}</div>'
                 + line("エイイチの考えに、ハコブくんが付き合う", T(9, 1.3), size=34, weight=500)
                 + '</div>', 0.0)
block("title_kabe", [9], title_kabe)

# ================= 2 持ち込み（脱線: 朝の街・ボタン1回目） =================
def bring(T, E):
    fly = (T(13, 0.3), E(13) - 0.1)
    col = lambda kind, head, sub, t: (f'<div class="card k-{kind}" style="width:420px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards">'
                                      f'<span class="serif" style="font-size:56px;font-weight:900;line-height:1.3">{head}</span><br><span style="font-size:28px">{sub}</span></div>')
    return (dassen(BG + "朝の街.jpg", fly[0] + 0.05, fly[1], words="一夜で、|<br>|!来ない。", word_style="top:150px;font-size:120px", src_note=GEM)
            + paper(tag("持ち込み") + '<div class="stack" style="top:100px;gap:26px">'
                    + line("エイイチが持ち込んだ、X の議論", T(10, 0.4), size=28, weight=500, style="color:#5a564f")
                    + f'<div class="serif" style="font-size:46px;font-weight:700;line-height:1.4">{ink("ロボットにも、", T(11, 0.4), 0.06)}<br>'
                      f'{land("ChatGPT の瞬間", T(11, 1.4), "font-size:84px;font-weight:900")}{ink("は来る？", T(11, 2.4), 0.08)}</div>'
                    + '<div style="position:relative;width:900px;height:200px">'
                    + f'<div style="position:absolute;left:0;right:0;top:20px;display:flex;justify-content:center;animation:hide .2s linear {T(15, 0.2):.3f}s forwards">'
                    + card("hb", "明日の朝、僕にも来る", T(13, 0.4), "ハコブくん", w=460, botsu=E(13) + 0.1, fade=T(14, 0.3), style="font-size:30px") + '</div>'
                    + f'<div class="row2" style="gap:30px;position:absolute;left:0;right:0;top:0">'
                    + col("hb", "ChatGPT", "開けば、すぐ試せる", T(15, 0.4))
                    + col("fact", "ロボット", "置く場所・止まったとき・店のやり方", T(16, 0.5))
                    + '</div></div></div>', 0.0, flights=[fly])
            + btn(T(16, S(16) + 0.2), T(17, -0.25), T(17, 1.2)))
block("bring", [10, 11, 12, 13, 14, 15, 16, 17], bring)

# ================= 3 やり取り1：なぜ配膳ロボットが先に広がったか =================
def why(T, E):
    big = lambda txt, t: (f'<div class="card k-fact" style="width:400px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards">'
                          f'<span class="serif" style="font-size:64px;font-weight:900;line-height:1.3">{txt}</span></div>')
    return paper(tag("やり取り 1 ／ どんな仕事から？") + '<div class="stack" style="top:110px;gap:34px">'
                 + qline("どんな仕事から、広がるのか", T(18, 0.3), size=48)
                 + f'<div class="row2" style="gap:34px">{big("失敗が<br>許せる", T(18, 2.8))}{big("繰り返しが<br>多い", T(18, 4.2))}</div>'
                 + card("mi", inkl("データも取りやすい。入れるハードルも低い。／広がり始めたのも、このあたり", T(19, 0.4), 0.045), T(19, 0.15), "見立て ・ エイイチ", w=860, anim="wipe")
                 + '</div>', 0.0)
block("why", [18, 19, 20], why)


def first(T, E):
    c = lambda txt, t: (f'<div class="card k-fact" style="width:300px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards;font-size:32px;padding:20px 18px">{txt}</div>')
    return (paper(tag("ファミレスの配膳ロボット") + '<div class="stack" style="top:110px;gap:30px">'
                  + qline("条件が、全部そろっていた", T(21, 0.8), size=50)
                  + card("mi", inkl("とうとうロボットが店舗に入った！", T(22, 0.5), 0.06), T(22, 0.2), "エイイチ（初めて店で見たとき）", w=820, anim="wipe", style="font-size:42px;font-weight:700")
                  + f'<div class="row2" style="gap:18px;margin-top:20px">{c("止まっても、<br>料理が少し遅れるだけ", T(24, 0.3))}{c("毎日、<br>何百回も往復する", T(24, 2.6))}{c("ホールの人が<br>集まらない", T(24, 4.2))}</div>'
                  + '</div>', 0.0)
            + stamp("感激", T(22, 3.0), "right:380px;top:300px;font-size:64px")
            + shake_js([(T(22, 3.35), 0.3)]))
block("first", [21, 22, 23, 24], first)


def last(T, E):
    tf = T(27, S(27) - 0.5)
    fly = (T(27, S(27) + 0.1), T(28, 0.7))
    return (dassen(BG + "最後の動作.jpg", fly[0] + 0.05, fly[1] - 0.05, words="!最後の|動作。", word_style="top:90px;font-size:130px", src_note=GEM)
            + paper(tag("一番難しい所") + '<div class="stack" style="top:100px;gap:22px">'
                    + qline("一番難しい所を、ロボットにやらせていない", T(25, 0.3), size=40)
                    + '<div class="row2" style="gap:24px">'
                    + card("fact", '<span style="white-space:nowrap">料理をテーブルに置く</span><br><b style="font-size:44px">お客さん</b>', T(26, 0.3), None, w=420)
                    + card("fact", '<span style="white-space:nowrap">トレーに載せる</span><br><b style="font-size:44px">店員さん</b>', T(26, 2.2), None, w=420)
                    + '</div>'
                    + card("hb", "料理も、僕が置く", T(27, 0.6), "ハコブくん", w=420, botsu=T(28, 0.9), fade=T(28, 1.1), style="font-size:30px")
                    + card("mi", inkl("だから、人に任せた", T(28, 0.9), 0.06), T(28, 0.75), "エイイチ", w=480, anim="wipe")
                    + qline("頑張らない所を決めて、広がった", T(29, 1.6), size=40)
                    + '</div>', 0.0, flights=[fly])
            + f'<div class="big" style="left:60px;right:auto;top:600px;font-size:96px;transform:rotate(-8deg)"><span style="animation:boom .3s cubic-bezier(.2,1.8,.4,1) {tf + 0.3:.3f}s forwards, hide .2s linear {fly[0]:.3f}s forwards">ドテッ</span></div>'
            + shake_js([(tf + 0.3, 0.25)]))
block("last", [25, 26, 27, 28, 29], last)

# ================= 4 山場：扱えるか =================
def card_mi_float(T):
    """店のスタッフさんでも使えてる（エイイチ）を紙の上部に"""
    return (f'<div style="position:absolute;left:520px;top:110px;width:880px;display:flex;justify-content:center">'
            + card("mi", inkl("店のスタッフさんでも使えてる。ポイント高い", T(32, 0.4), 0.05), T(32, 0.15), "エイイチ", w=820, anim="wipe", fade=T(33, 0.0))
            + '</div>')


def easy(T, E):
    press = T(31, 1.6)
    return (BTN_CSS + paper(tag("もう1つの強み") + '<div class="center" style="gap:26px">'
                  + line("使い方は、テーブル番号のボタンを押すだけ", T(31, 0.2), size=34, weight=700)
                  + f'<div style="display:flex;gap:26px">' + ''.join(
                      f'<div style="width:130px;height:110px;border-radius:20px;border:6px solid #141311;box-shadow:0 10px 0 #141311;display:flex;align-items:center;justify-content:center;'
                      f'font-family:\'Noto Sans CJK JP\';font-weight:900;font-size:52px;opacity:0;animation:pop .35s ease-out {T(31, 0.6 + 0.15 * k):.3f}s forwards'
                      + (f', press .35s ease-out {press:.3f}s' if k == 2 else '') + f'">{k + 1}</div>' for k in range(4)) + '</div>'
                  + card("mi", inkl("店のスタッフさんでも使えてる。ポイント高い", T(32, 0.4), 0.05), T(32, 0.15), "エイイチ", w=820, anim="wipe")
                  + f'<div class="serif" style="font-size:44px;font-weight:700;margin-top:4px">{ink("研修もマニュアルも、", T(33, 0.3), 0.06)}{land("ほぼ不要", T(33, 2.0), "font-size:70px;font-weight:900")}</div>'
                  + card("hb", inkl("賢くても、止まったときにどうすればいいか／分からなければ、広がらない", T(34, 0.8), 0.04), T(34, 0.5), "裏を返すと", w=900)
                  + '</div>', 0.0)
            + f'<div class="big" style="left:900px;right:auto;top:300px;font-size:80px;transform:rotate(-6deg)"><span style="animation:boom .3s cubic-bezier(.2,1.8,.4,1) {press:.3f}s forwards, hide .2s linear {press + 1.0:.3f}s forwards">ピッ</span></div>'
            )
block("easy", [30, 31, 32, 33, 34], easy)


def peak(T, E):
    return ('<div style="position:absolute;inset:0;background:#141311"></div>'
            '<div class="paper" style="opacity:.08"></div>'
            '<div class="center" style="left:430px;width:1060px;right:auto;top:64px;height:780px;bottom:auto;gap:40px">'
            '<p class="v" style="color:#e9e5dc;font-size:60px;line-height:1.7;font-weight:500;letter-spacing:.08em;">'
            f'<span data-ink="{T(35, 0.6):.2f},0.1">止まったとき、</span><br>'
            f'<span data-ink="{T(35, 1.6):.2f},0.1">店の人が</span><br>'
            f'{land("戻せる", T(35, 2.6), "font-weight:900;font-size:84px")}<span data-ink="{T(35, 3.1):.2f},0.1">か。</span></p>'
            f'<div style="{SANS}font-size:26px;color:#bdb7ab;opacity:0;animation:show .3s linear {T(35, 4.0):.3f}s forwards">ハコブくんの整理 ／ エイイチ「そうなんだよな」</div>'
            '</div>')
block("peak", [35], peak)


def q3(T, E):
    row = lambda b, txt, t, sub="": (f'<div class="trow" style="width:880px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards">'
                                     f'<b>{b}</b><span>{txt}<div style="font-size:22px;color:#5a564f;margin-top:4px">{sub}</div></span></div>')
    return paper(tag("見極めの、3つの問い") + '<div class="stack" style="top:130px;gap:22px">'
                 + row("1つ目", "止まった理由が、分かるか", T(37, 0.3), "通れません／物を見失いました")
                 + row("2つ目", "その場の人が、戻せるか", T(38, 0.3), "エンジニアを呼ばずに")
                 + row("3つ目", "次の動きが、周りに読めるか", T(39, 0.3), "読めないと、怖い")
                 + '</div>', 0.0)
block("q3", [36, 37, 38, 39], q3)


def demo(T, E):
    return (paper(tag("デモの点数") + '<div class="center" style="gap:30px">'
                  + qline("この3つは、技術のデモでは", T(40, 0.3), size=46)
                  + f'<div class="serif" style="font-size:46px;font-weight:700">{land("ほとんど評価されない", T(40, 1.8), "font-size:60px;font-weight:900")}</div>'
                  + card("mi", inkl("デモの点数には、入らない", T(41, 0.4), 0.06), T(41, 0.15), "エイイチ", w=600, anim="wipe")
                  + card("hb", "さっきコケた所は、点数に入れないで", T(42, 1.0), "ハコブくん", w=640, style="font-size:30px")
                  + '</div>', 0.0)
            + stamp("入れとく", T(43, 0.05), "right:380px;top:640px;font-size:56px")
            + shake_js([(T(43, 0.4), 0.25)]))
block("demo", [40, 41, 42, 43], demo)

# ================= 5 やり取り2：足りなくなるのは誰か（ボタン2回目） =================
def who(T, E):
    return (paper(tag("やり取り 2 ／ 足りなくなるのは誰か") + '<div class="stack" style="top:100px;gap:26px">'
                  + line("動き回る仕事のロボットは、機体が", T(44, 2.0), size=34, weight=700)
                  + f'<div class="serif" style="font-size:120px;font-weight:900;line-height:1.1">{land("安く↓", T(44, 4.6))}</div>'
                  + card("mi", inkl("その分、入れる営業や／エンジニアが足りなくなる", T(46, 0.4), 0.05), T(45, 0.15), "見立て ・ エイイチ", w=760, anim="wipe")
                  + card("mi", inkl("利益が残るのは、／作る側より、入れて回す側", T(47, 0.4), 0.05), T(47, 0.15), "見立て ・ エイイチ", w=820, anim="wipe", style="font-size:38px;font-weight:700")
                  + '</div>', 0.0)
            + stamp("この見立ては、エイイチから", T(47, S(47) + 0.1), "left:1060px;top:150px")
            + shake_js([(T(47, S(47) + 0.45), 0.3)]))
block("who", [44, 45, 46, 47], who)


def who2(T, E):
    row = lambda txt, t: f'<div class="trow" style="width:820px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards"><span>{txt}</span></div>'
    return (paper(tag("足りなくなる人") + '<div class="stack" style="top:110px;gap:18px">'
                  + qline("足りなくなるのは、こんな人", T(48, 0.2), size=42)
                  + row("通路の幅や段差を見る", T(48, 1.8))
                  + row("どこまでロボットに任せるか、線を引く", T(48, 3.6))
                  + row("止まったときの対処を、店のルールにする", T(48, 5.8))
                  + card("hb", "今みたいに戻してくれる人が、足りない", T(49, 1.0), "ハコブくん", w=680, style="font-size:30px;margin-top:16px")
                  + '</div>', 0.0)
            + btn(T(48, S(48) + 0.2), T(49, -0.25), T(49, 1.2)))
block("who2", [48, 49], who2)


def local(T, E):
    return paper(tag("地方では") + '<div class="stack" style="top:80px;gap:12px">'
                 + card("mi", inkl("入れるのは、地方の方が切実。／どう解決できるかが鍵", T(50, 0.4), 0.045), T(50, 0.15), "見立て ・ エイイチ", w=860, anim="wipe")
                 + card("mi", inkl("家電量販店や電気屋さんは、どうだろう？", T(51, 0.4), 0.05), T(51, 0.15), "エイイチ", w=720, anim="wipe")
                 + '<div class="row2" style="gap:22px;align-items:stretch">'
                 + card("fact", '町の電気屋さん<br><span style="font-size:28px">すぐ来てくれる関係がある<br>→ 止まったときの駆けつけ</span>', T(52, 0.3), None, w=420)
                 + card("hb", '任せる線を、<br>店と決める<br><span style="font-size:28px">まだ、どちらにもない<br>→ 離れた所から専門の人</span>', T(53, 0.4), None, w=420)
                 + '</div>'
                 + card("mi", inkl("役割を分ける", T(54, 0.3), 0.06), T(54, 0.1), "エイイチ", w=380, anim="wipe")
                 + '</div>', 0.0)
block("local", [50, 51, 52, 53, 54], local)

# ================= 6 やり取り3：止まらない作りと、扉 =================
def iris(T, E):
    big = lambda el, unit, t: f'<div class="num" style="font-size:110px;line-height:1.1"><span id="{el}">0</span><span style="font-size:48px">{unit}</span></div>'
    return (paper(tag("やり取り 3 ／ アイリスオーヤマは？") + '<div class="stack" style="top:96px;gap:16px">'
                  + card("mi", inkl("アイリスオーヤマは、どうしてる？", T(55, 0.4), 0.05), T(55, 0.15), "エイイチ", w=640, anim="wipe")
                  + f'<div class="row2" style="gap:60px;align-items:flex-end">{big("c7k", "社以上", T(56, 1.0))}{big("c25k", "台以上", T(56, 2.6))}</div>'
                  + card("fact", inkl("充電切れ・紙パックがいっぱい、で、／すぐ人の作業に戻る", T(57, 0.5), 0.04), T(57, 0.2), "事業の責任者", w=880)
                  + card("fact", inkl("運用を直し続ける人が、現場にいない", T(58, 0.5), 0.05), T(58, 0.2), "広める上での壁", w=720)
                  + '</div>' + src("出どころ：マイナビニュース（2026-06-29）", T(56, 0.3)), 0.0)
            + counter_js("c7k", T(56, 1.6), T(56, 3.0), 7000, dec=0) + counter_js("c25k", T(56, 3.0), T(56, 4.4), 25000, dec=0))
block("iris", [55, 56, 57, 58], iris)


def iris2(T, E):
    return paper(tag("止まらない作り") + '<div class="center" style="gap:30px">'
                 + '<div class="row2" style="gap:24px">'
                 + card("fact", "掃除が終わると、自分で充電に戻る", T(59, 1.2), "新しい清掃ロボ", w=430)
                 + card("fact", "紙パックを、替えやすく", T(59, 3.6), "新しい清掃ロボ", w=380)
                 + '</div>'
                 + f'<div class="serif" style="font-size:150px;font-weight:900;line-height:1.1">{land("紙パック", T(60, 0.2))}</div>'
                 + line("直し続ける人がいないなら、人を呼ばない作りにする", T(60, 1.6), size=30, weight=500)
                 + card("mi", inkl("家電の会社らしい", T(61, 0.3), 0.06), T(61, 0.1), "エイイチ", w=440, anim="wipe")
                 + '</div>' + src("出どころ：マイナビニュース（2026-06-29）"), 0.0)
block("iris2", [59, 60, 61], iris2)


def door(T, E):
    fly = (T(63, S(63) - 0.8), T(64, 0.25))
    return (dassen(BG + "扉.jpg", fly[0] + 0.05, fly[1] - 0.05, words="開けて……。", word_style="top:60px;font-size:120px", src_note=GEM)
            + paper(tag("残る壁") + '<div class="stack" style="top:110px;gap:26px">'
                    + qline("残る壁は、下げ膳", T(62, 0.3), size=52)
                    + line("食べ終わったお皿を、洗い場まで運ぶ仕事", T(62, 2.0), size=30, weight=500)
                    + card("mi", inkl("バックヤードに行くには、／扉を開けられないといけない", T(63, 0.4), 0.045), T(63, 0.15), "見立て ・ エイイチ", w=880, anim="wipe")
                    + card("hb", "扉は、体当たりで開ける", T(64, 0.5), "ハコブくん", w=500, botsu=E(64) - 0.6, style="font-size:30px")
                    + '</div>', 0.0, flights=[fly]))
block("door", [62, 63, 64], door)


def door2(T, E):
    lab = lambda txt, t: f'<div style="{SANS}font-size:26px;font-weight:700;color:#5a564f;height:40px;text-align:center">{ink(txt, t, 0.05)}</div>'
    seg = lambda txt, w, bg, fg, t: (f'<div class="seg" style="width:{w}px;background:{bg};color:{fg};clip-path:inset(0 100% 0 0);animation:wipe .45s ease-out {t:.3f}s forwards">{txt}</div>')
    return paper(tag("扉を通らない手") + '<div class="stack" style="top:100px;gap:16px">'
                 + line("求められるのは、調理場と客席の仕切り", T(65, 0.4), size=34, weight=700)
                 + line("形は、地域の決まりや保健所の判断で変わる", T(65, 3.4), size=26, weight=500, style="color:#5a564f")
                 + '<div style="height:20px"></div>'
                 + '<div style="display:flex;width:900px">'
                 + f'<div style="width:300px">{lab("洗い場側", T(66, 1.0))}</div><div style="width:300px">{lab("両側から取り出せる棚", T(66, 1.8))}</div><div style="width:300px">{lab("客席側", T(66, 1.0))}</div></div>'
                 + '<div style="display:flex;width:900px">'
                 + seg("調理場", 300, "#cfc8ba", "#22201c", T(66, 1.2)) + seg("棚", 300, "#22201c", "#f5f3ee", T(66, 2.6)) + seg("ロボット", 300, "#ece9e2", "#22201c", T(66, 4.4))
                 + '</div>'
                 + '<div style="height:20px"></div>'
                 + card("mi", inkl("現場設計だね。／直接、洗い場まで行けたら最高", T(67, 0.4), 0.05), T(67, 0.15), "見立て ・ エイイチ", w=760, anim="wipe")
                 + line("新しい店や改装のときに、通り道ごと設計する", T(68, 0.8), size=30, weight=700)
                 + '</div>' + src("出どころ：食品衛生法の施設基準（例：那覇市・北九州市の基準）", T(65, 0.3)), 0.0)
block("door2", [65, 66, 67, 68], door2)

# ================= 7 まとめ =================
SUM_CSS = """@keyframes gather { from { opacity:0; transform: translate(var(--dx),var(--dy)) rotate(var(--r)); } to { opacity:1; transform: none; } }"""


def summ(T, E):
    row = lambda b, mid, dx, dy, r, t: (f'<div class="trow" style="--dx:{dx}px;--dy:{dy}px;--r:{r}deg;opacity:0;'
                                       f'animation:gather .9s cubic-bezier(.3,1.2,.4,1) {t:.3f}s forwards"><b style="width:230px">{b}</b><span>{mid}</span></div>')
    b3 = lambda txt, t: card("hb", txt, t, None, w=290, botsu=t + 0.25, style="font-size:22px;padding:10px 12px;white-space:nowrap")
    return ('<style>' + SUM_CSS + '</style>'
            + paper(tag("残っている壁") + '<div class="stack" style="top:76px;gap:10px">'
                    + row("店の作り", "扉・通路・下げ台", 420, 420, 8, T(70, 3.0))
                    + row("仕事の分け方", "置くのは人、運ぶのはロボット", 300, -60, -6, T(70, 4.2))
                    + row("調整", "保健所・地域の決まり", -420, 180, 10, T(70, 5.4))
                    + f'<p class="serif" style="margin-top:12px;text-align:center;font-size:40px;line-height:1.55;font-weight:900;">'
                      f'{ink("決めていたのは、店の人が自分で扱えるように、", T(71, 0.3), 0.05)}<br>{land("作業と店の作りを、切り直せるか。", T(71, 3.2), "font-size:50px")}</p>'
                    + f'<div class="row2" style="gap:20px;margin-top:8px">{b3("明日の朝、僕にも来る", T(72, 1.4))}{b3("料理も僕が置く", T(72, 1.8))}{b3("扉は体当たり", T(72, 2.2))}</div>'
                    + card("mi", inkl("全部やらなくていい", T(73, 0.3), 0.06), T(73, 0.1), "エイイチ", w=440, anim="wipe", style="padding:10px 30px")
                    + '</div>', 0.0))
block("sum", [69, 70, 71, 72, 73], summ)

# ================= 8 残った問い（ボタン3回目・自分で押す） =================
def rest(T, E):
    return paper(tag("残った問い") + '<div class="stack" style="top:100px;gap:22px">'
                 + card("mi", inkl("この辺の問題を解決する力を持つ人が、／重宝されそう", T(74, 0.4), 0.045), T(74, 0.15), "見立て ・ エイイチ", w=860, anim="wipe")
                 + qline("店とロボットのあいだに立つ役", T(75, 0.4), size=46)
                 + f'<div class="serif" style="font-size:40px;font-weight:700">{ink("名前も、求人の枠も、", T(75, 3.8), 0.06)}{land("まだない", T(75, 5.2), "font-size:64px;font-weight:900")}</div>'
                 + card("mi", inkl("大型のお店から、スタートしたい", T(77, 0.3), 0.06), T(77, 0.1), "エイイチ", w=620, anim="wipe")
                 + card("hb", '考察ノートの全文<div style="font-size:24px;color:#5a564f;margin-top:4px">pixelstomotors.com ／ LOG389</div>', T(79, 0.3), "サイトの記事", w=600)
                 + '</div>', 0.0)
block("rest", [74, 75, 76, 77, 78, 79], rest)


def ask(T, E):
    return (paper(tag("あなたの店では") + '<div class="center" style="gap:12px">'
                  + qline("あなたの店で", T(80, 0.2), size=56)
                  + qline("ロボットが止まったら、", T(80, 1.0), size=56)
                  + qline("誰が戻しますか。", T(80, 2.2), size=56)
                  + '<div style="height:40px"></div>'
                  + card("mi", inkl("それが一番えらい", T(82, 0.3), 0.06), T(82, 0.1), "エイイチ", w=440, anim="wipe")
                  + '</div>', 0.0)
            + btn(T(80, S(80) + 0.3), T(81, -0.3), T(81, 1.0), who="自分で押す"))
block("ask", [80, 81, 82], ask)

# ================= 9 アウトロ =================
block("outro", [83, 84, 85], None, video=("src/day124_crop.mp4", 18.0, "png/ovl/outro.png"))

assert [i for b in BLOCKS for i in b["sents"]] == list(range(N)), "場面の文の番号が抜けている・重なっている"

# ================= ハコブくん =================
# 表情は narration.py の表情が基本。ここは文の途中で替える所: (文, 文の頭から何秒, 何秒間, 表情)
HK_FACE = [
    (3, 0.0, 2.0, "doubt"),
    (16, S(16) + 0.1, 1.4, "dot"),            # 固まる（ボタン1回目）
    (22, 0.0, 4.5, "joy"),
    (27, S(27) - 0.5, 3.0, "x"),              # コケる
    (28, 0.0, 2.0, "x"),
    (35, 0.0, 6.0, "think"),
    (43, 0.0, 1.5, "trouble"),
    (47, 0.0, 4.0, "surprise"),
    (48, S(48) + 0.1, 1.4, "dot"),            # 固まる（ボタン2回目）
    (60, 0.0, 2.0, "surprise"),
    (63, 0.0, 4.0, "trouble"),
    (80, S(80) + 0.2, 1.3, "dot"),            # 固まる（自分で押す）
]
HK_FACE = [(A(i, a), A(i, a) + d, f) for i, a, d, f in HK_FACE]

# 体ごとの動き: jump＝驚いて全身で飛び出す / fall＝前のめりにコケる（up で起き上がる） / reflex＝のけぞる
HK_MOVES = [
    dict(kind="fall", t0=A(27, S(27) - 0.5), t1=A(29, 0.0), dur=0.5),
    dict(kind="jump", t0=A(60, 0.0), dur=1.9),
]
HK_ALPHA = [(A(35, 0.0), tl.end(35), 0.3),                         # 暗い場面では薄く
            (A(27, S(27) + 0.15), A(28, 0.65), 0.0),               # 最後の動作の絵にはハコブくんが描いてあるので、重ねない
            (A(63, S(63) - 0.75), A(64, 0.2), 0.0)]                 # 扉の絵も同じ

# ================= エイイチ =================
# (文, 文の頭から何秒, 姿) 1腕組み 2うなずく 3指さす 4首をかしげる 5ひらめく 6のけぞって驚く 7半目でツッコむ 8吹き出して笑う
EI_POSE = [
    (0, 0.0, 1), (2, 0.5, 4), (3, 0.0, 7), (4, 1.0, 8), (5, 0.0, 1),
    (8, 0.0, 2), (9, 0.0, 1),
    (10, 0.0, 3), (12, 0.0, 4), (13, 0.3, 6), (14, 0.0, 1), (16, S(16) + 0.1, 3), (17, 0.8, 2),
    (18, 0.0, 1), (19, 0.0, 2), (20, 0.0, 3), (21, 0.0, 2), (22, 0.0, 5), (23, 0.5, 8), (24, 0.0, 1),
    (25, 0.0, 4), (27, 0.0, 4), (27, S(27) - 0.4, 6), (28, 0.0, 7), (29, 0.6, 2),
    (30, 0.0, 1), (32, 0.0, 3), (33, 0.0, 2), (34, 0.0, 1), (35, 0.0, 2),
    (36, 0.0, 1), (39, 0.0, 4), (40, 0.0, 2), (41, 0.0, 3), (42, 0.5, 8), (43, 0.0, 3),
    (44, 0.0, 1), (45, 0.0, 3), (47, 0.0, 5), (48, 0.0, 2), (48, S(48) + 0.1, 3), (49, 0.8, 2),
    (50, 0.0, 3), (51, 0.0, 4), (52, 0.0, 2), (54, 0.0, 3),
    (55, 0.0, 4), (56, 1.0, 6), (57, 0.0, 1), (59, 0.0, 2), (60, 0.0, 6), (61, 0.0, 8),
    (62, 0.0, 1), (63, 0.0, 3), (64, 0.0, 7), (65, 0.0, 1), (67, 0.0, 3), (68, 0.0, 2),
    (69, 0.0, 2), (72, 0.8, 8), (73, 0.0, 3),
    (74, 0.0, 3), (75, 0.0, 2), (76, 0.0, 4), (77, 0.0, 5), (78, 0.0, 1), (79, 0.0, 2),
    (80, 0.0, 1), (81, 0.0, 6), (82, 0.0, 8),
    (83, 0.0, 2),
]
EI_POSE = sorted((A(i, a), p) for i, a, p in EI_POSE)
# 置き方の替え: (開始, 終了, 置き方)。hide＝出さない / big＝暗い場面で大きく光らせる
EI_PLACE = [
    (A(6), tl.end(7), "hide"),
    (A(35), tl.end(35), "big"),
]

# ================= 効果音 =================
# (文, 文の頭から何秒, 音, ナレーションより何dB)
SE = [
    (3, 0.3, "se_pop", -8), (22, 3.0, "se_pop", -8), (31, 1.6, "se_ding", -10), (44, 4.6, "se_pop", -10), (11, 1.4, "se_pop", -12),
    (2, 0.1, "se_whoosh", -10), (3, 0.15, "se_whoosh", -14),
    (13, 0.3, "se_whoosh", -10), (13, 99, "se_pop", -12),
    (16, S(16) + 0.2, "se_pop", -12), (17, -0.25, "se_ding", -10),
    (27, S(27) - 0.2, "se_whoosh", -12), (27, S(27) + 0.05, "se_pop", -6), (28, 0.7, "se_whoosh", -14), (28, 0.9, "se_pop", -12),
    (43, 0.05, "se_pop", -8),
    (47, S(47) + 0.1, "se_pop", -8),
    (48, S(48) + 0.2, "se_pop", -12), (49, -0.25, "se_ding", -10),
    (60, 0.0, "se_rise", -10),
    (63, S(63) - 0.8, "se_whoosh", -10), (64, 0.25, "se_whoosh", -14), (64, 1.6, "se_pop", -12),
    (72, 1.65, "se_pop", -14), (72, 2.05, "se_pop", -14), (72, 2.45, "se_pop", -14),
    (80, S(80) + 0.3, "se_pop", -12), (81, -0.3, "se_ding", -10),
]
SE = [s for s in SE if s[1] != 99]

# 一覧の画像に撮る時刻（場面の頭からの秒）。書かない場面は最後の0.4秒前
def _rel(b, i, off=0.0):
    return tl.start(i) - _tl.start(b["sents"][0]) + off
SHEET = {}
for _b in BLOCKS:
    _end = _tl.end(_b["sents"][-1]) - _tl.start(_b["sents"][0]) - 0.4
    SHEET[_b["name"]] = [_end]
_B = {b["name"]: b for b in BLOCKS}
SHEET["hook"] = [_rel(_B["hook"], 1, 5.0), _rel(_B["hook"], 2, 1.5), SHEET["hook"][0]]
SHEET["easy"] = [_rel(_B["easy"], 32, 1.5), _rel(_B["easy"], 31, 1.8), SHEET["easy"][0]]
SHEET["door2"] = [_rel(_B["door2"], 66, 6.0), SHEET["door2"][0]]
SHEET["bring"] = [_rel(_B["bring"], 13, 2.0), _rel(_B["bring"], 16, S(16) + 0.6), SHEET["bring"][0]]
SHEET["last"] = [_rel(_B["last"], 27, S(27) - 0.1), _rel(_B["last"], 27, S(27) + 1.0), SHEET["last"][0]]
SHEET["who2"] = [_rel(_B["who2"], 48, S(48) + 0.6), SHEET["who2"][0]]
SHEET["iris2"] = [_rel(_B["iris2"], 60, 0.8), SHEET["iris2"][0]]
SHEET["door"] = [_rel(_B["door"], 63, S(63) - 0.2), SHEET["door"][0]]
SHEET["ask"] = [_rel(_B["ask"], 80, S(80) + 0.6), SHEET["ask"][0]]
SHEET["title"] = [2.0]
```

### scenes_kabe.py の v2 から v3 への差分（diff -u の出力）

```diff
--- scenes_kabe_v1.py	2026-11-02 16:11:42.137351787 +0900
+++ scenes_kabe.py	2026-11-02 16:14:36.072069820 +0900
@@ -75,17 +75,15 @@
 def hook(T, E):
     fly = (T(2, 0.1), T(3, 0.15))
     return (dassen(BG + "1時間に6回.jpg", fly[0] + 0.05, fly[1] - 0.05, words="!1時間に|6回。", word_style="top:120px;font-size:130px", src_note=GEM)
-            + paper(tag("考察ノート") + '<div class="stack" style="top:110px;gap:24px">'
-                    + line("仮に、成功率", T(0, 0.2), size=32, weight=500)
-                    + f'<div class="num" style="font-size:190px;line-height:1.05">{land("99%", T(0, 0.9))}</div>'
-                    + f'<div class="row2" style="align-items:center;gap:20px">'
-                    + card("fact", '<span style="font-size:30px">1時間に600回働くと　</span>'
-                           f'<span class="num" style="font-size:64px"><span id="c6">0</span>回</span><span style="font-size:30px">　人が駆けつける</span>', T(1, 0.6), None, w=880)
-                    + '</div>'
-                    + card("mi", inkl("それ、優秀なのかな", T(3, 0.3), 0.06), T(3, 0.1), "エイイチ", w=520, anim="wipe")
-                    + card("hb", "僕も、自信がなくなってきた", T(4, 0.6), "ハコブくん", w=560, style="font-size:30px")
+            + paper(tag("考察ノート") + '<div class="center" style="gap:6px">'
+                    + line("仮に、成功率", T(0, 0.2), size=34, weight=500)
+                    + f'<div class="num" style="font-size:230px;line-height:1.05"><span id="c99">0</span><span style="font-size:110px">%</span></div>'
+                    + f'<div class="serif" style="font-size:44px;font-weight:700;margin-top:10px">{ink("1時間に600回働くと、", T(1, 0.3), 0.06)}</div>'
+                    + f'<div class="serif" style="font-size:44px;font-weight:700">{land("6回", T(1, 3.0), "font-size:120px;font-weight:900")}{ink("人が駆けつける", T(1, 3.5), 0.07)}</div>'
                     + '</div>' + src("例の計算（X の議論の指摘をもとに）", T(0, 0.5)), 0.0, flights=[fly])
-            + counter_js("c6", T(1, 2.6), T(1, 4.2), 6, dec=0))
+            + stamp("優秀？", T(3, 0.3), "right:380px;top:560px;font-size:64px")
+            + shake_js([(T(3, 0.65), 0.3)])
+            + counter_js("c99", T(0, 1.0), T(0, 2.6), 99, dec=0))
 block("hook", [0, 1, 2, 3, 4], hook)
 
 
@@ -118,38 +116,44 @@
 # ================= 2 持ち込み（脱線: 朝の街・ボタン1回目） =================
 def bring(T, E):
     fly = (T(13, 0.3), E(13) - 0.1)
+    col = lambda kind, head, sub, t: (f'<div class="card k-{kind}" style="width:420px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards">'
+                                      f'<span class="serif" style="font-size:56px;font-weight:900;line-height:1.3">{head}</span><br><span style="font-size:28px">{sub}</span></div>')
     return (dassen(BG + "朝の街.jpg", fly[0] + 0.05, fly[1], words="一夜で、|<br>|!来ない。", word_style="top:150px;font-size:120px", src_note=GEM)
-            + paper(tag("持ち込み") + '<div class="stack" style="top:90px;gap:20px">'
-                    + line("エイイチが持ち込んだ、X の議論", T(10, 0.4), size=28, weight=500)
-                    + qline("ロボットにも、ChatGPT の瞬間は来る？", T(11, 0.4))
-                    + card("hb", "明日の朝、僕にも来る", T(13, 0.4), "ハコブくん", w=460, botsu=E(13) + 0.1, fade=T(14, 0.3), style="font-size:30px")
-                    + card("fact", inkl("できるようになる瞬間は来ても、広がるには時間がかかる", T(14, 0.5), 0.04), T(14, 0.2), "議論の声", w=880)
-                    + '<div class="row2" style="gap:24px">'
-                    + card("hb", "ブラウザを開けば試せる", T(15, 0.4), "ChatGPT", w=400, style="font-size:28px")
-                    + card("fact", "置く場所・止まったときの対処・店のやり方", T(16, 0.5), "ロボット", w=480, style="font-size:28px")
-                    + '</div></div>', 0.0, flights=[fly])
+            + paper(tag("持ち込み") + '<div class="stack" style="top:100px;gap:26px">'
+                    + line("エイイチが持ち込んだ、X の議論", T(10, 0.4), size=28, weight=500, style="color:#5a564f")
+                    + f'<div class="serif" style="font-size:46px;font-weight:700;line-height:1.4">{ink("ロボットにも、", T(11, 0.4), 0.06)}<br>'
+                      f'{land("ChatGPT の瞬間", T(11, 1.4), "font-size:84px;font-weight:900")}{ink("は来る？", T(11, 2.4), 0.08)}</div>'
+                    + '<div style="position:relative;width:900px;height:200px">'
+                    + f'<div style="position:absolute;left:0;right:0;top:20px;display:flex;justify-content:center;animation:hide .2s linear {T(15, 0.2):.3f}s forwards">'
+                    + card("hb", "明日の朝、僕にも来る", T(13, 0.4), "ハコブくん", w=460, botsu=E(13) + 0.1, fade=T(14, 0.3), style="font-size:30px") + '</div>'
+                    + f'<div class="row2" style="gap:30px;position:absolute;left:0;right:0;top:0">'
+                    + col("hb", "ChatGPT", "開けば、すぐ試せる", T(15, 0.4))
+                    + col("fact", "ロボット", "置く場所・止まったとき・店のやり方", T(16, 0.5))
+                    + '</div></div></div>', 0.0, flights=[fly])
             + btn(T(16, S(16) + 0.2), T(17, -0.25), T(17, 1.2)))
 block("bring", [10, 11, 12, 13, 14, 15, 16, 17], bring)
 
 # ================= 3 やり取り1：なぜ配膳ロボットが先に広がったか =================
 def why(T, E):
-    return paper(tag("やり取り 1 ／ どんな仕事から？") + '<div class="stack" style="top:110px;gap:26px">'
-                 + qline("どんな仕事から、広がるのか", T(18, 0.3))
-                 + card("hb", "失敗が許せて、繰り返しの多い作業", T(18, 2.6), "ハコブくん", w=640)
-                 + card("mi", inkl("データも取りやすい。入れるハードルも低い。／お金もかからない", T(19, 0.4), 0.04), T(19, 0.15), "見立て ・ エイイチ", w=880, anim="wipe")
-                 + card("mi", inkl("サービスロボットが広がり始めたのも、／このあたり", T(20, 0.4), 0.045), T(20, 0.15), "見立て ・ エイイチ", w=820, anim="wipe")
+    big = lambda txt, t: (f'<div class="card k-fact" style="width:400px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards">'
+                          f'<span class="serif" style="font-size:64px;font-weight:900;line-height:1.3">{txt}</span></div>')
+    return paper(tag("やり取り 1 ／ どんな仕事から？") + '<div class="stack" style="top:110px;gap:34px">'
+                 + qline("どんな仕事から、広がるのか", T(18, 0.3), size=48)
+                 + f'<div class="row2" style="gap:34px">{big("失敗が<br>許せる", T(18, 2.8))}{big("繰り返しが<br>多い", T(18, 4.2))}</div>'
+                 + card("mi", inkl("データも取りやすい。入れるハードルも低い。／広がり始めたのも、このあたり", T(19, 0.4), 0.045), T(19, 0.15), "見立て ・ エイイチ", w=860, anim="wipe")
                  + '</div>', 0.0)
 block("why", [18, 19, 20], why)
 
 
 def first(T, E):
-    c = lambda txt, t: card("fact", txt, t, None, w=290, style="font-size:28px;padding:16px 18px")
-    return paper(tag("ファミレスの配膳ロボット") + '<div class="stack" style="top:100px;gap:24px">'
-                 + qline("条件が、全部そろっていた", T(21, 0.8))
-                 + card("mi", inkl("とうとうロボットが店舗に入った！", T(22, 0.5), 0.06), T(22, 0.2), "エイイチ（初めて店で見たとき）", w=760, anim="wipe", style="font-size:38px;font-weight:700")
-                 + card("hb", "同じロボットとして、ありがとうございます", T(23, 1.2), "ハコブくん", w=640, style="font-size:28px")
-                 + f'<div class="row2" style="gap:18px">{c("止まっても、<br>料理が少し遅れるだけ", T(24, 0.3))}{c("毎日、<br>何百回も往復する", T(24, 2.6))}{c("ホールの人が<br>集まらない", T(24, 4.2))}</div>'
-                 + '</div>', 0.0)
+    c = lambda txt, t: (f'<div class="card k-fact" style="width:300px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards;font-size:32px;padding:20px 18px">{txt}</div>')
+    return (paper(tag("ファミレスの配膳ロボット") + '<div class="stack" style="top:110px;gap:30px">'
+                  + qline("条件が、全部そろっていた", T(21, 0.8), size=50)
+                  + card("mi", inkl("とうとうロボットが店舗に入った！", T(22, 0.5), 0.06), T(22, 0.2), "エイイチ（初めて店で見たとき）", w=820, anim="wipe", style="font-size:42px;font-weight:700")
+                  + f'<div class="row2" style="gap:18px;margin-top:20px">{c("止まっても、<br>料理が少し遅れるだけ", T(24, 0.3))}{c("毎日、<br>何百回も往復する", T(24, 2.6))}{c("ホールの人が<br>集まらない", T(24, 4.2))}</div>'
+                  + '</div>', 0.0)
+            + stamp("感激", T(22, 3.0), "right:380px;top:300px;font-size:64px")
+            + shake_js([(T(22, 3.35), 0.3)]))
 block("first", [21, 22, 23, 24], first)
 
 
@@ -160,8 +164,8 @@
             + paper(tag("一番難しい所") + '<div class="stack" style="top:100px;gap:22px">'
                     + qline("一番難しい所を、ロボットにやらせていない", T(25, 0.3), size=40)
                     + '<div class="row2" style="gap:24px">'
-                    + card("fact", '料理をテーブルに<br>置く<br><b style="font-size:40px">お客さん</b>', T(26, 0.3), None, w=400)
-                    + card("fact", 'トレーに載せる<br><b style="font-size:40px">店員さん</b>', T(26, 2.2), None, w=400)
+                    + card("fact", '<span style="white-space:nowrap">料理をテーブルに置く</span><br><b style="font-size:44px">お客さん</b>', T(26, 0.3), None, w=420)
+                    + card("fact", '<span style="white-space:nowrap">トレーに載せる</span><br><b style="font-size:44px">店員さん</b>', T(26, 2.2), None, w=420)
                     + '</div>'
                     + card("hb", "料理も、僕が置く", T(27, 0.6), "ハコブくん", w=420, botsu=T(28, 0.9), fade=T(28, 1.1), style="font-size:30px")
                     + card("mi", inkl("だから、人に任せた", T(28, 0.9), 0.06), T(28, 0.75), "エイイチ", w=480, anim="wipe")
@@ -172,13 +176,27 @@
 block("last", [25, 26, 27, 28, 29], last)
 
 # ================= 4 山場：扱えるか =================
+def card_mi_float(T):
+    """店のスタッフさんでも使えてる（エイイチ）を紙の上部に"""
+    return (f'<div style="position:absolute;left:520px;top:110px;width:880px;display:flex;justify-content:center">'
+            + card("mi", inkl("店のスタッフさんでも使えてる。ポイント高い", T(32, 0.4), 0.05), T(32, 0.15), "エイイチ", w=820, anim="wipe", fade=T(33, 0.0))
+            + '</div>')
+
+
 def easy(T, E):
-    return paper(tag("もう1つの強み") + '<div class="stack" style="top:100px;gap:22px">'
-                 + card("fact", inkl("テーブル番号のボタンを押すだけ。／止まったら、どかす", T(31, 0.3), 0.04), T(31, 0.1), "使い方", w=880)
-                 + card("mi", inkl("店のスタッフさんでも使えてる。ポイント高い", T(32, 0.4), 0.05), T(32, 0.15), "エイイチ", w=820, anim="wipe")
-                 + card("fact", inkl("研修もマニュアルも、ほとんどいらない", T(33, 0.3), 0.05), T(33, 0.1), "入れたあと", w=720)
-                 + card("hb", inkl("賢くても、止まったときにどうすればいいか／分からなければ、広がらない", T(34, 0.8), 0.04), T(34, 0.5), "裏を返すと", w=900)
-                 + '</div>', 0.0)
+    press = T(31, 1.6)
+    return (BTN_CSS + paper(tag("もう1つの強み") + '<div class="center" style="gap:26px">'
+                  + line("使い方は、テーブル番号のボタンを押すだけ", T(31, 0.2), size=34, weight=700)
+                  + f'<div style="display:flex;gap:26px">' + ''.join(
+                      f'<div style="width:130px;height:110px;border-radius:20px;border:6px solid #141311;box-shadow:0 10px 0 #141311;display:flex;align-items:center;justify-content:center;'
+                      f'font-family:\'Noto Sans CJK JP\';font-weight:900;font-size:52px;opacity:0;animation:pop .35s ease-out {T(31, 0.6 + 0.15 * k):.3f}s forwards'
+                      + (f', press .35s ease-out {press:.3f}s' if k == 2 else '') + f'">{k + 1}</div>' for k in range(4)) + '</div>'
+                  + card("mi", inkl("店のスタッフさんでも使えてる。ポイント高い", T(32, 0.4), 0.05), T(32, 0.15), "エイイチ", w=820, anim="wipe")
+                  + f'<div class="serif" style="font-size:44px;font-weight:700;margin-top:4px">{ink("研修もマニュアルも、", T(33, 0.3), 0.06)}{land("ほぼ不要", T(33, 2.0), "font-size:70px;font-weight:900")}</div>'
+                  + card("hb", inkl("賢くても、止まったときにどうすればいいか／分からなければ、広がらない", T(34, 0.8), 0.04), T(34, 0.5), "裏を返すと", w=900)
+                  + '</div>', 0.0)
+            + f'<div class="big" style="left:900px;right:auto;top:300px;font-size:80px;transform:rotate(-6deg)"><span style="animation:boom .3s cubic-bezier(.2,1.8,.4,1) {press:.3f}s forwards, hide .2s linear {press + 1.0:.3f}s forwards">ピッ</span></div>'
+            )
 block("easy", [30, 31, 32, 33, 34], easy)
 
 
@@ -219,12 +237,13 @@
 
 # ================= 5 やり取り2：足りなくなるのは誰か（ボタン2回目） =================
 def who(T, E):
-    return (paper(tag("やり取り 2 ／ 足りなくなるのは誰か") + '<div class="stack" style="top:100px;gap:24px">'
-                  + line("動き回る仕事のロボットは、機体が安くなってきた", T(44, 2.0), size=32, weight=700)
-                  + card("mi", inkl("移動系は早く、安くなる。／その分、入れる営業やエンジニアが足りなくなる", T(45, 0.4), 0.04), T(45, 0.15), "見立て ・ エイイチ", w=900, anim="wipe")
+    return (paper(tag("やり取り 2 ／ 足りなくなるのは誰か") + '<div class="stack" style="top:100px;gap:26px">'
+                  + line("動き回る仕事のロボットは、機体が", T(44, 2.0), size=34, weight=700)
+                  + f'<div class="serif" style="font-size:120px;font-weight:900;line-height:1.1">{land("安く↓", T(44, 4.6))}</div>'
+                  + card("mi", inkl("その分、入れる営業や／エンジニアが足りなくなる", T(46, 0.4), 0.05), T(45, 0.15), "見立て ・ エイイチ", w=760, anim="wipe")
                   + card("mi", inkl("利益が残るのは、／作る側より、入れて回す側", T(47, 0.4), 0.05), T(47, 0.15), "見立て ・ エイイチ", w=820, anim="wipe", style="font-size:38px;font-weight:700")
                   + '</div>', 0.0)
-            + stamp("この見立ては、エイイチから", T(47, S(47) + 0.1), "left:740px;top:640px")
+            + stamp("この見立ては、エイイチから", T(47, S(47) + 0.1), "left:1060px;top:150px")
             + shake_js([(T(47, S(47) + 0.45), 0.3)]))
 block("who", [44, 45, 46, 47], who)
 
@@ -293,10 +312,19 @@
 
 
 def door2(T, E):
-    return paper(tag("扉を通らない手") + '<div class="stack" style="top:96px;gap:20px">'
-                 + card("fact", inkl("求められるのは、調理場と客席の仕切り。／形は、地域の決まりや保健所の判断で変わる", T(65, 0.4), 0.035), T(65, 0.15), "決まり", w=900)
-                 + card("hb", inkl("両側から取り出せる棚を客席側に置き、／トレーを置くだけ", T(66, 1.6), 0.04), T(66, 1.3), "扉を通らない", w=880)
-                 + card("mi", inkl("現場設計だね。／直接、洗い場まで行けたら最高", T(67, 0.4), 0.05), T(67, 0.15), "見立て ・ エイイチ", w=780, anim="wipe")
+    lab = lambda txt, t: f'<div style="{SANS}font-size:26px;font-weight:700;color:#5a564f;height:40px;text-align:center">{ink(txt, t, 0.05)}</div>'
+    seg = lambda txt, w, bg, fg, t: (f'<div class="seg" style="width:{w}px;background:{bg};color:{fg};clip-path:inset(0 100% 0 0);animation:wipe .45s ease-out {t:.3f}s forwards">{txt}</div>')
+    return paper(tag("扉を通らない手") + '<div class="stack" style="top:100px;gap:16px">'
+                 + line("求められるのは、調理場と客席の仕切り", T(65, 0.4), size=34, weight=700)
+                 + line("形は、地域の決まりや保健所の判断で変わる", T(65, 3.4), size=26, weight=500, style="color:#5a564f")
+                 + '<div style="height:20px"></div>'
+                 + '<div style="display:flex;width:900px">'
+                 + f'<div style="width:300px">{lab("洗い場側", T(66, 1.0))}</div><div style="width:300px">{lab("両側から取り出せる棚", T(66, 1.8))}</div><div style="width:300px">{lab("客席側", T(66, 1.0))}</div></div>'
+                 + '<div style="display:flex;width:900px">'
+                 + seg("調理場", 300, "#cfc8ba", "#22201c", T(66, 1.2)) + seg("棚", 300, "#22201c", "#f5f3ee", T(66, 2.6)) + seg("ロボット", 300, "#ece9e2", "#22201c", T(66, 4.4))
+                 + '</div>'
+                 + '<div style="height:20px"></div>'
+                 + card("mi", inkl("現場設計だね。／直接、洗い場まで行けたら最高", T(67, 0.4), 0.05), T(67, 0.15), "見立て ・ エイイチ", w=760, anim="wipe")
                  + line("新しい店や改装のときに、通り道ごと設計する", T(68, 0.8), size=30, weight=700)
                  + '</div>' + src("出どころ：食品衛生法の施設基準（例：那覇市・北九州市の基準）", T(65, 0.3)), 0.0)
 block("door2", [65, 66, 67, 68], door2)
@@ -323,10 +351,10 @@
 
 # ================= 8 残った問い（ボタン3回目・自分で押す） =================
 def rest(T, E):
-    return paper(tag("残った問い") + '<div class="stack" style="top:96px;gap:20px">'
-                 + card("mi", inkl("この辺の問題を解決する力を持つ人が、／重宝されそう", T(74, 0.4), 0.045), T(74, 0.15), "見立て ・ エイイチ", w=880, anim="wipe")
-                 + qline("店とロボットのあいだに立つ役", T(75, 0.4), size=44)
-                 + line("名前も、求人の枠も、まだない", T(75, 4.2), size=28, weight=500, style="color:#5a564f")
+    return paper(tag("残った問い") + '<div class="stack" style="top:100px;gap:22px">'
+                 + card("mi", inkl("この辺の問題を解決する力を持つ人が、／重宝されそう", T(74, 0.4), 0.045), T(74, 0.15), "見立て ・ エイイチ", w=860, anim="wipe")
+                 + qline("店とロボットのあいだに立つ役", T(75, 0.4), size=46)
+                 + f'<div class="serif" style="font-size:40px;font-weight:700">{ink("名前も、求人の枠も、", T(75, 3.8), 0.06)}{land("まだない", T(75, 5.2), "font-size:64px;font-weight:900")}</div>'
                  + card("mi", inkl("大型のお店から、スタートしたい", T(77, 0.3), 0.06), T(77, 0.1), "エイイチ", w=620, anim="wipe")
                  + card("hb", '考察ノートの全文<div style="font-size:24px;color:#5a564f;margin-top:4px">pixelstomotors.com ／ LOG389</div>', T(79, 0.3), "サイトの記事", w=600)
                  + '</div>', 0.0)
@@ -405,6 +433,7 @@
 # ================= 効果音 =================
 # (文, 文の頭から何秒, 音, ナレーションより何dB)
 SE = [
+    (3, 0.3, "se_pop", -8), (22, 3.0, "se_pop", -8), (31, 1.6, "se_ding", -10), (44, 4.6, "se_pop", -10), (11, 1.4, "se_pop", -12),
     (2, 0.1, "se_whoosh", -10), (3, 0.15, "se_whoosh", -14),
     (13, 0.3, "se_whoosh", -10), (13, 99, "se_pop", -12),
     (16, S(16) + 0.2, "se_pop", -12), (17, -0.25, "se_ding", -10),
@@ -427,7 +456,9 @@
     _end = _tl.end(_b["sents"][-1]) - _tl.start(_b["sents"][0]) - 0.4
     SHEET[_b["name"]] = [_end]
 _B = {b["name"]: b for b in BLOCKS}
-SHEET["hook"] = [_rel(_B["hook"], 2, 1.5), SHEET["hook"][0]]
+SHEET["hook"] = [_rel(_B["hook"], 1, 5.0), _rel(_B["hook"], 2, 1.5), SHEET["hook"][0]]
+SHEET["easy"] = [_rel(_B["easy"], 32, 1.5), _rel(_B["easy"], 31, 1.8), SHEET["easy"][0]]
+SHEET["door2"] = [_rel(_B["door2"], 66, 6.0), SHEET["door2"][0]]
 SHEET["bring"] = [_rel(_B["bring"], 13, 2.0), _rel(_B["bring"], 16, S(16) + 0.6), SHEET["bring"][0]]
 SHEET["last"] = [_rel(_B["last"], 27, S(27) - 0.1), _rel(_B["last"], 27, S(27) + 1.0), SHEET["last"][0]]
 SHEET["who2"] = [_rel(_B["who2"], 48, S(48) + 0.6), SHEET["who2"][0]]
```

### kabe_kit.py の差分（作り手のドット絵の下を3ドット伸ばした・diff -u の出力）

```diff
--- "\347\217\276\345\240\264\343\201\247\346\211\261\343\201\210\343\202\213\343\201\213/kabe_kit.py"	2026-11-02 13:59:50.000000000 +0900
+++ "/home/claude/work/\347\217\276\345\240\264\343\201\247\346\211\261\343\201\210\343\202\213\343\201\213/kabe_kit.py"	2026-11-02 14:55:59.626380676 +0900
@@ -222,7 +222,14 @@
         for k, n in self.POSES.items():
             fs = [f for f in os.listdir(folder) if f.startswith(f"エイイチ_{n}_100px")]
             im = Image.open(os.path.join(folder, sorted(fs)[-1])).convert("RGBA")
-            self.raw[k] = fill_teeth(im)
+            im = fill_teeth(im)
+            # 声に合わせて上に弾むと、画面の下に隙間が見える（2026-11-02 エイイチの指摘）。一番下の行を3ドットぶん下へ伸ばしておく
+            ext = Image.new("RGBA", (im.width, im.height + 3), (0, 0, 0, 0))
+            ext.paste(im, (0, 0))
+            last = im.crop((0, im.height - 1, im.width, im.height))
+            for r in range(3):
+                ext.paste(last, (0, im.height + r))
+            self.raw[k] = ext
         self._cache = {}
 
     def sprite(self, pose, scale=4, glow=False, crop=1.0):
```

### sound.py（BGM と章の効果音。効果音の時刻は scenes_kabe.py の SE）

```python
# 音の置き方（audio_mix.py が読む）。効果音の時刻は scenes_kabe.py の SE に書く（場面の動きと同じ所で決めるため）
# 書き写した元: 頭脳は脳のように分かれる/sound.py
from scenes_kabe import SE as _SE

BGM = [
    dict(file='sound/bgm_明るいB_2.mp3', start=0, end=None, level=-26, gap=-19, fade_in=0.6, fade_out=3.0),   # 考察回なのでいつもより3dB小さく
]

SE = list(_SE)

CHAPTER_SE = dict(file='se_chapter_marimba', files={'title': 'se_chapter_glock'}, level=-10, offset=-0.3,
                  scenes=['title', 'bring', 'why', 'easy', 'who', 'iris_ei', 'sum', 'outro'])
```

### 脱線の絵のプロンプト：1時間に6回（1時間に6回_プロンプト.txt）

```text
Black and white Japanese manga illustration.
ART STYLE: match the attached reference manga page from the series "Hakobu" EXACTLY — the same clean, slightly realistic Japanese manga line art, the same line weight, the same halftone-dot screentone and flat gray tones, the same realistic proportions and faces for people, the same crisp white backgrounds. Do NOT copy any text or speech bubbles from the reference page.
USE THE ATTACHED REFERENCE for the robot "Hakobu" — match its body shape, screen face (simple black screen with white oval eyes and a small smile line), round side window, wheels, line weight and screentone exactly. Hakobu is a delivery robot: a rounded box body with a screen for a face. Hakobu has NO arms and NO hands.
Scene: inside a busy Japanese family restaurant. Three serving robots that all look exactly like Hakobu, each carrying a tray of food on its top, are stuck and stopped in different places in the aisles: one facing a wall, one blocked by a chair, one with dizzy spiral eyes on its screen.
One restaurant staff member (a young woman in an apron and cap, drawn in the same realistic style as the people in the reference) is sprinting between them, sweating, pushing one robot with both hands while looking back at another. Speed lines drawn as plain lines only. Diners at the tables keep eating calmly.
Comedic, energetic.
Keep the upper center area relatively plain so text can be placed over it. No text, no letters, no numbers, no symbols, no question marks, no sound-effect lettering, no speech bubbles anywhere in the image. All menus, signs and posters are blank. One wide 16:9 panel, the artwork fills the whole image with no panel border and no frame line.
```

### 脱線の絵のプロンプト：朝の街（朝の街_プロンプト.txt）

```text
Photorealistic wide cinematic photograph, 16:9 landscape.
Early morning in an ordinary Japanese shopping street, golden sunrise light. Overnight, dozens of sleek humanoid robots have suddenly appeared everywhere: standing at the crosswalk, sweeping shop fronts, holding coffee cups, waving. Ordinary commuters have all stopped in their tracks and are filming the robots with their smartphones, mouths open in surprise.
The mood is a slightly absurd daydream, like a movie poster for "the morning the world changed overnight".
Keep the upper center area calm (sky) so large text can be placed over it. One continuous seamless photograph.
No text, no letters, no signs with readable words, no logos.
All shop signs, banners and noren curtains are plain solid colors with absolutely no characters, kanji, kana or letters on them.
ABSOLUTELY NO TEXT OR WRITING OF ANY KIND ANYWHERE.
```

### 脱線の絵のプロンプト：最後の動作（最後の動作_プロンプト.txt）

```text
Black and white Japanese manga illustration.
ART STYLE: match the attached reference manga page from the series "Hakobu" EXACTLY — the same clean, slightly realistic Japanese manga line art, the same line weight, the same halftone-dot screentone and flat gray tones, the same realistic proportions and faces for people, the same crisp white backgrounds. Do NOT copy any text or speech bubbles from the reference page.
USE THE ATTACHED REFERENCE for the robot "Hakobu" — match its body shape, screen face (simple black screen with white oval eyes and a small smile line), round side window, wheels, line weight and screentone exactly. Hakobu is a delivery robot: a rounded box body with a screen for a face. Hakobu has NO arms and NO hands.
Scene: in a Japanese family restaurant, Hakobu has tried to put a meal on a customer's table by itself and has tipped forward in a dramatic face-plant in front of the table. Its screen face shows X-shaped eyes. The plates of food (a hamburg steak, a bowl of rice, a bowl of miso soup) are flying through the air above it in a frozen moment, sauce splashing. A seated middle-aged customer leans back in shock.
Comedic slapstick, in the calm realistic manga style of the reference.
Keep the upper center area relatively plain so text can be placed over it. No text, no letters, no numbers, no symbols, no question marks, no sound-effect lettering, no speech bubbles anywhere in the image. All menus, signs and posters are blank. One wide 16:9 panel, the artwork fills the whole image with no panel border and no frame line.
```

### 脱線の絵のプロンプト：扉（扉_プロンプト.txt）

```text
Black and white Japanese manga illustration.
ART STYLE: match the attached reference manga page from the series "Hakobu" EXACTLY — the same clean, slightly realistic Japanese manga line art, the same line weight, the same halftone-dot screentone and flat gray tones, the same realistic proportions and faces for people, the same crisp white backgrounds. Do NOT copy any text or speech bubbles from the reference page.
USE THE ATTACHED REFERENCE for the robot "Hakobu" — match its body shape, screen face (simple black screen with white oval eyes and a small smile line), round side window, wheels, line weight and screentone exactly. Hakobu is a delivery robot: a rounded box body with a screen for a face. Hakobu has NO arms and NO hands.
Scene: one image split visually into two halves side by side without any border line: on the left it is late night, on the right it is the next morning. In both halves, Hakobu stands in exactly the same spot in front of a closed swinging kitchen door of a restaurant (the back-of-house door), carrying a tray stacked with dirty dishes on top of its body, staring at the door and waiting patiently.
Left half: dark night drawn with dense screentone, moon visible through a small window, Hakobu's screen shows hopeful eyes.
Right half: bright morning light through the same window, Hakobu now with a little dust and a small cobweb, screen showing tired half-closed eyes and a small sweat drop.
Comedic and a little sad.
Keep the upper center area relatively plain so text can be placed over it. No text, no letters, no numbers, no symbols, no question marks, no sound-effect lettering, no speech bubbles anywhere in the image. All menus, signs and posters are blank. One wide 16:9 panel, the artwork fills the whole image with no panel border and no frame line.
```

### サムネイルの背景のプロンプト（店とロボ_プロンプト.txt）

```text
A photorealistic, cinematic photograph for a YouTube thumbnail background. Inside a warm, modern Japanese family restaurant in the evening. In the center-right of the frame: a white boxy serving robot with a tray of food on top has stopped in the aisle, slightly crooked, its screen glowing blank. A restaurant staff member in an apron (seen from behind and the side, face not visible) is reaching out with one finger toward the robot's screen, as if to press a restart button. Soft bokeh lights, shallow depth of field.
The left 45 percent of the image must be calm, darker, softly blurred restaurant background (for large text added later). The bottom-right corner should also be relatively plain.
Seamless single photograph. No text, no letters, no numbers, no logos, no readable signs, no visible faces, no watermark. 16:9.
```

### thumb_A.py（サムネイル A 案・決めた案）

```python
# サムネイル A 案（2026-11-02）: 問いの答えをそのまま大きく。「賢さ」を打ち消して「戻せるか」を強く
PHOTO = 'サムネ素材/店とロボ.jpg'
PHOTO_POS_FULL = '50% 50%'
HAKOBU = True
KICKER = 'ロボットが店に広がる条件'
LINES = ['賢さ、', 'じゃなかった', '']
LABEL = '止まったら、誰が戻す？'
VARIANTS = ['photo4']
SIZE_L1, SIZE_L2, SIZE_L3 = 180, 150, 10
TXT_TOP = 60
HK_H = 560
LABEL_BOTTOM = 250
```

### thumb_B.py（サムネイル B 案）

```python
# サムネイル B 案（2026-11-02）: つかみの数字。成功率99%でも10分に1回呼ばれる
PHOTO = 'サムネ素材/店とロボ.jpg'
PHOTO_POS_FULL = '50% 50%'
HAKOBU = True
KICKER = '配膳ロボット'
LINES = ['成功率99%でも', '<span style="color:#F5A04A">10分に1回</span>', '呼ばれる']
LABEL = '優秀……ですか？'
VARIANTS = ['photo4']
SIZE_L1, SIZE_L2, SIZE_L3 = 120, 170, 120
TXT_TOP = 60
HK_H = 560
LABEL_BOTTOM = 250
```

### 概要欄_下書き.md（目次の時間は {t:文番号} で書き、description.py が置きかえる）

```markdown
<!--
YouTube の概要欄の下書き（2026-11-02「現場で扱えるか」＝考察回「壁打ちの型」の2本目・もとは LOG389）。{t:文番号} は、その文が始まる時間に置きかわる（文番号は 0 から数える）。
python3 <_制作ベース>/description.py で 概要欄.txt を作り、それを貼る。
-->
仮に成功率99%でも、1時間に600回働けば、1時間に6回は人が駆けつけることになる。ロボットが店に広がるかを決めるのは、賢さなのか。エイイチが持ち込んだ X の議論に、案内役のハコブくんが付き合う「考察回」です。答えを伝える回ではなく、考えている途中をそのまま見せます。配膳ロボットが先に広がった条件、止まったときに店の人が戻せるか、下げ膳と調理場の扉の壁までを考えました。

詳しい調べと考えた道すじは、サイトの記事にまとめています。
記事：ロボットを広げるのは、性能より現場で扱えるかだった https://pixelstomotors.com/record/service-robot-last-mile

▼目次
0:00 成功率99%でも、10分に1回
{t:6} この番組について
{t:10} 持ち込み：ロボットにも ChatGPT の瞬間は来る？
{t:18} やり取り1：なぜ配膳ロボットが先に広がったか
{t:30} 止まったとき、店の人が戻せるか
{t:44} やり取り2：足りなくなるのは誰か
{t:55} やり取り3：止まらない作りと、扉
{t:69} まとめ
{t:74} 残った問い
{t:83} エンディング

▼出どころ
・成功率99%・1時間に600回・1時間に6回：X の議論の中の指摘をもとにした、例の計算です（実在の機体の数字ではありません）
・X の議論：Joe Harris さんの投稿 https://x.com/_joe_harris_/status/2114504443895128326 ／ Hugh Phan さんの投稿 https://x.com/hughphan_/status/2114510937998983463
・アイリスオーヤマの導入実績（7000社以上・2万5000台以上）、事業の責任者の話、新しい清掃ロボ（JILBY）の自動充電と紙パック：マイナビニュース（2026年6月29日） https://news.mynavi.jp/article/newsinsight-463/
・調理場と客席の仕切り（食品衛生法の施設基準。形は自治体や保健所の判断による）：那覇市 https://www.city.naha.okinawa.jp/nahahokenjyo/0004/kyokashinsei.files/setsubi.pdf ／ 北九州市 https://www.city.kitakyushu.lg.jp/files/001117944.pdf

▼この動画について
・エイイチのセリフは、記事を書く前のやり取りで本人が話した言葉と、動画のために本人に聞いた答えを、話し言葉に整えたものです。短い相づちやツッコミの一部は、本人が了承した案です
・「止まったとき、店の人が戻せるか」の3つの問いと、扉を通らない手（両側から取り出せる棚）は、ハコブくん（Claude）の整理です
・決まりの細かい条件は地域で変わります。店に入れるときは、地域の保健所に確かめてください

▼この番組について
「フィジカルAI解説｜Pixels to Motors」は、フィジカルAIのニュースや実機の記録から、現場で使える形を考える番組です。
エイイチは、本業のデザイナーをしながら、ロボティクスの研究と開発をしています。その中で分かったことと、そこから考えた見立てを、案内役のハコブくんがお伝えします。

・ナレーションは AI 音声（ElevenLabs）です。話しているのは Pixels to Motors のキャラクター、ハコブくんです
・エイイチの声も AI 音声で、本人の声ではありません
・ファミレスの店員さん・コケるハコブくん・扉の前で待つハコブくんのマンガの絵、朝の街の絵、サムネイルの背景は、生成AI（Gemini）で作成しています
・実機の映像はエイイチが撮ったものです

▼ロボットの開発・導入のご相談
メール：pixelstomotors@adaptdesign.jp

▼リンク
Webサイト：https://pixelstomotors.com
4コママンガ『ハコブくん』：https://pixelstomotors.com/manga-archive
GitHub：https://github.com/PixelstoMotors
X：https://x.com/adaptdesignjp
LinkedIn：https://www.linkedin.com/in/eiichi-shimazu

チャンネル登録・高評価もよろしくお願いします。コメントは、エイイチが全部読んでいます。

#フィジカルAI #配膳ロボット #ロボット
```

### mot.py（1秒に10コマずつ縮小した画面で、動いている時間と写真が出ている時間を数えた）

```python
import subprocess, numpy as np, sys
def stats(path):
    W,H=192,108
    p=subprocess.Popen(['ffmpeg','-v','error','-i',path,'-vf',f'fps=10,scale={W}:{H}','-f','rawvideo','-pix_fmt','rgb24','-'],stdout=subprocess.PIPE)
    prev=None; diffs=[]; colorful=[]
    while True:
        b=p.stdout.read(W*H*3)
        if len(b)<W*H*3: break
        f=np.frombuffer(b,np.uint8).reshape(H,W,3).astype(np.int16)
        # paper area (x 43-149, y 6-84 in 192x108)
        pap=f[8:82,45:147]
        # is a photo shown? paper mostly near #f5f3ee or dark; photo = high saturation/variance in background margins
        bgm=np.concatenate([f[:, 150:180].reshape(-1,3), f[:6,:].reshape(-1,3)])
        colorful.append(bgm.std()>25)
        if prev is not None: diffs.append(np.abs(f-prev).mean())
        prev=f
    d=np.array(diffs); n=len(d)/10
    print(path.split('/')[-1], f'{n:.0f}s', 'moving(>0.5) %.0f%%'%(100*(d>0.5).mean()), 'big(>3) %.0f%%'%(100*(d>3).mean()), 'photo-ish %.0f%%'%(100*np.mean(colorful)))
    # per 30s bins
    bins=[f'{100*(d[i:i+300]>0.5).mean():.0f}' for i in range(0,len(d),300)]
    print(' per30s moving%:', ' '.join(bins))
for a in sys.argv[1:]: stats(a)
```

### mot.py の出力（1本目と、2本目 v3）

```text
頭脳は脳のように分かれる.mp4 425s moving(>0.5) 16% big(>3) 7% photo-ish 23%
 per30s moving%: 8 29 10 22 37 12 9 19 7 13 13 13 7 21 6
out.mp4 515s moving(>0.5) 13% big(>3) 6% photo-ish 20%
 per30s moving%: 18 33 11 11 10 16 7 6 9 9 6 18 17 6 9 4 24 8
```

### 書き出しのログ：v3（python3 kabe_kit.py build の出力）

```text
  hook: 701コマ（撮影 225）
  bring: 1494コマ（撮影 260）
  why: 552コマ（撮影 147）
  first: 748コマ（撮影 171）
  last: 753コマ（撮影 230）
  easy: 816コマ（撮影 245）
  who: 711コマ（撮影 210）
  door2: 1028コマ（撮影 275）
  rest: 990コマ（撮影 213）
BGM 1本・効果音 38個 → mix.wav
   17.57秒  文003  se_pop  -8dB  「それ、優秀なのかな。」
  135.87秒  文022  se_pop  -8dB  「初めて店で見たときは、とうとうロ」
  183.67秒  文031  se_ding  -10dB  「使い方は、テーブル番号のボタンを」
  256.00秒  文044  se_pop  -10dB  「話を、店の外に広げます。配膳や清」
   67.37秒  文011  se_pop  -12dB  「お題は、ロボットにも、ChatG」
   12.43秒  文002  se_whoosh  -10dB  「店の人からすると、10分に1回、」
   17.42秒  文003  se_whoosh  -14dB  「それ、優秀なのかな。」
   75.70秒  文013  se_whoosh  -10dB  「来ます。明日の朝、僕にも来ます。」
  103.30秒  文016  se_pop  -12dB  「ロボットは、置く場所を空けて、止」
  104.35秒  文017  se_ding  -10dB  「……失礼しました。今のが、止まっ」
  167.83秒  文027  se_whoosh  -12dB  「では僕が、料理もテーブルに置きま」
  168.08秒  文027  se_pop  -6dB  「では僕が、料理もテーブルに置きま」
  170.23秒  文028  se_whoosh  -14dB  「だから人に任せたんだよ。」
  170.43秒  文028  se_pop  -12dB  「だから人に任せたんだよ。」
  248.95秒  文043  se_pop  -8dB  「入れとくよ。」
  274.40秒  文047  se_pop  -8dB  「ロボットで利益が残るのは、作る側」
  284.67秒  文048  se_pop  -12dB  「足りなくなるのは、店の通路の幅や」
  285.72秒  文049  se_ding  -10dB  「……ありがとうございます。今みた」
  365.23秒  文060  se_rise  -10dB  「……紙パックです。直し続ける人が」
  387.37秒  文063  se_whoosh  -10dB  「ロボットがお店のフロントからバッ」
  389.92秒  文064  se_whoosh  -14dB  「大丈夫です。扉は、体当たりで開け」
  391.27秒  文064  se_pop  -12dB  「大丈夫です。扉は、体当たりで開け」
  448.95秒  文072  se_pop  -14dB  「ちなみに、ボツになった3つは、全」
  449.35秒  文072  se_pop  -14dB  「ちなみに、ボツになった3つは、全」
  449.75秒  文072  se_pop  -14dB  「ちなみに、ボツになった3つは、全」
  492.80秒  文080  se_pop  -12dB  「あなたの店でロボットが止まったら」
  493.70秒  文081  se_ding  -10dB  「自分で戻りました。」
   31.13秒  文006  se_chapter_glock  -10dB  「Pixels to Motors」
   59.93秒  文010  se_chapter_marimba  -10dB  「エイイチが持ち込んだのは、海外の」
  109.73秒  文018  se_chapter_marimba  -10dB  「では、どんな仕事から広がるのか。」
  128.13秒  文021  se_chapter_marimba  -10dB  「ファミレスの配膳ロボットは、その」
  178.17秒  文030  se_chapter_marimba  -10dB  「もう1つ、配膳ロボットには強みが」
  191.60秒  文033  se_chapter_marimba  -10dB  「研修もマニュアルも、ほとんどいり」
  251.10秒  文044  se_chapter_marimba  -10dB  「話を、店の外に広げます。配膳や清」
  274.80秒  文048  se_chapter_marimba  -10dB  「足りなくなるのは、店の通路の幅や」
  328.53秒  文055  se_chapter_marimba  -10dB  「アイリスオーヤマが、ロボットを扱」
  428.13秒  文069  se_chapter_marimba  -10dB  「ここまでを、1枚にまとめます。」
  498.90秒  文083  se_chapter_marimba  -10dB  「この動画が役に立ったら、高評価と」
  900/15459
  1800/15459
  2700/15459
  3600/15459
  4500/15459
  5400/15459
  6300/15459
  7200/15459
  8100/15459
  9000/15459
  9900/15459
  10800/15459
  11700/15459
  12600/15459
  13500/15459
  14400/15459
  15300/15459
frames 15459 = 515.3s  確認用 22.8MB (crf 29)
```

### kabe_short.py（縦長ショート3本。dash・fall・wall の動きと、壁の方を向く反転を足した最終版）

```python
# -*- coding: utf-8 -*-
"""考察回「壁打ちの型」の縦長ショート（1080×1920）。2本目「現場で扱えるか」用（中身の3本だけ書き替えた。部品は1本目の版2のまま）。\n1本目の版2の説明:
2026-11-02 エイイチの指摘で作り直した:
  「おれが上半身で、ハコブくんが全身は変」→ エイイチも全身のドット絵（src/ei/エイイチ_全身_*_170px_v1.png・Gemini で写真の服装から作った）
  「この始まりだとすぐ離脱しそう」「宇宙・紙の山・引退式の背景を使って、ハコブくんが大きく動く所から始める」
    → 最初の数秒は、画面いっぱいの絵の前で、大きなハコブくん（高さ900）が動く。本題に入ったら、絵を暗くして紙（考察ノート）を出し、
      ハコブくんは左下の全身（高さ400）に戻る
画面の割り振りは video_rules.md 9-2: 0〜150 何も置かない／170〜440 見出し／480〜1130 紙／左下 ハコブくん・右下 エイイチ（足もと y=1640）／字幕は2人の間の上
使い方: python3 kabe_short.py [番号 ...]
"""
import os, sys, json, wave, subprocess, html as _html
import numpy as np
from PIL import Image
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import kabe_kit as K
from kabe_kit import ink, land, card, counter_js, shake_js, ease, blend, rotate_about, hk, FPS, SR
sys.path.insert(1, K.BASE)
import short_kit as SK
from scene_kit import LOGO

W, H = 1080, 1920
SANS = "font-family:'Noto Sans CJK JP',sans-serif;"
FOOT = 1880                     # 2人の足もと（下の方まで使ってよい・2026-11-02 エイイチ）
SUB_MID = 1150                  # 字幕の真ん中
SUB_CX, SUB_MAXC = 540, 11       # 字幕は画面の真ん中（2026-11-02 エイイチの指摘で 470 から直した）・1行11字
EI_SCALE, EI_X = 4.5, None         # エイイチの全身（170px の4.5倍＝高さ765・右端に寄せる）。身長はエイイチ 1700mm・ハコブくん 1150mm（2026-11-02 エイイチ）
HK_SMALL_H, HK_X = 515, 10      # ふだんのハコブくん（全身）。765 × 1150/1700
HK_BIG_H = 900                  # 最初の数秒の大きなハコブくん
EI_POSES = {1: "立つ", 2: "腕組み", 3: "驚く", 4: "笑う"}

VCSS = """
html, body { width:1080px; height:1920px; }
.f { width:1080px; height:1920px; }
.vhead { position:absolute; left:60px; right:60px; top:170px; height:270px; display:flex; flex-direction:column; justify-content:center; align-items:center; text-align:center; z-index:5; }
.vhead img { height:54px; align-self:flex-start; margin-bottom:18px; filter:invert(1) drop-shadow(0 0 6px rgba(0,0,0,.8)); opacity:.9; }
.vhead .q { font-family:'Noto Sans CJK JP',sans-serif; font-size:84px; font-weight:900; line-height:1.2; color:#f5f3ee; text-shadow:0 0 18px rgba(0,0,0,.9), 0 4px 0 #141311; }
.vpaper { position:absolute; left:100px; top:480px; width:880px; height:590px; background:#f5f3ee; box-shadow:0 30px 60px rgba(0,0,0,.45); opacity:0; }
.vpaper .card { font-size:40px; }
.vpaper .card small { font-size:24px; }
.vstack { position:absolute; left:0; right:0; top:40px; bottom:40px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:22px; }
.bgimg { position:absolute; inset:0; background-repeat:no-repeat; background-color:#fff; }
@keyframes veil { to { opacity:.74; } }
@keyframes pIn { from { opacity:0; transform:translateY(60px) rotate(-1.5deg); } to { opacity:1; transform:none; } }
.vbig { position:absolute; left:0; right:0; text-align:center; font-family:'Noto Sans CJK JP',sans-serif; font-weight:900; color:#fff; line-height:1.15;
        -webkit-text-stroke:5px #141311; paint-order:stroke fill; text-shadow:0 10px 0 #c4472a; z-index:6; }
.vbig span { display:inline-block; opacity:0; }
"""


def vpage(head, body):
    return K.page(body + f'<div class="vhead"><img src="{LOGO}"><div class="q">{head}</div></div>', VCSS)


def bg(img, size_h, pos_x, pos_y, t_veil):
    p = "file://" + os.path.abspath(img)
    return (f'<div class="bgimg" style="background-image:url(\'{p}\');background-size:auto {size_h}px;background-position:{pos_x}px {pos_y}px"></div>'
            '<div style="position:absolute;left:0;right:0;top:0;height:560px;background:linear-gradient(rgba(20,19,17,.78),rgba(20,19,17,.45) 70%,rgba(20,19,17,0))"></div>'   # 白いマンガの絵でも見出しが読めるように（2本目で足した）
            f'<div style="position:absolute;inset:0;background:#141311;opacity:0;animation:veil .5s ease {t_veil:.3f}s forwards"></div>'
            '<div style="position:absolute;right:100px;top:446px;font-family:\'Noto Sans CJK JP\';font-size:22px;color:#fff;opacity:.85;text-shadow:0 0 6px #000;z-index:7">絵は生成AI（Gemini）で作成</div>')


def paper(inner, t_in):
    return f'<div class="vpaper" style="animation:pIn .45s cubic-bezier(.2,1.2,.4,1) {t_in:.3f}s forwards">{inner}</div>'


def grp(inner, t_in=0.0, t_out=None):
    an = f"show .01s linear {t_in:.3f}s forwards" + (f", hide .2s linear {t_out:.3f}s forwards" if t_out is not None else "")
    return f'<div class="vstack" style="opacity:0;animation:{an}">{inner}</div>'


def line(text, t, size=40, weight=700, step=0.05, style=""):
    return f'<div style="{SANS}font-size:{size}px;font-weight:{weight};text-align:center;{style}">{ink(text, t, step)}</div>'


def words(rows, t0, t_out, top, size=130, gap=0.32):
    """大きな一言を1行ずつ叩きつける。rows は [(文字, 色)]"""
    out = []
    for k, (txt, col) in enumerate(rows):
        out.append(f'<span style="color:{col};animation:boom .32s cubic-bezier(.2,1.8,.4,1) {t0 + gap * k:.3f}s forwards, hide .2s linear {t_out:.3f}s forwards">{txt}</span>')
    return f'<div class="vbig" style="top:{top}px;font-size:{size}px;transform:rotate(-4deg)">{"<br>".join(out)}</div>'


def bigword(text, t, t_out, top, size=300, color="#c4472a", rot=-8):
    return (f'<div class="big" style="top:{top}px;font-size:{size}px;color:{color};-webkit-text-stroke:10px #fff;paint-order:stroke fill;'
            f'text-shadow:0 14px 0 #141311;transform:rotate({rot}deg);z-index:6"><span style="animation:boom .3s cubic-bezier(.2,1.8,.4,1) {t:.3f}s forwards, '
            f'hide .2s linear {t_out:.3f}s forwards">{text}</span></div>')


WHITE, GOLD = "#ffffff", "#ffd84a"


# ====================== 3本の中身（T(k, 秒) は k 番目の文の頭から。k=-1 は動画の頭） ======================
# 2026-11-02 考察回2本目「現場で扱えるか」（LOG389）の3本。書き写した元: 頭脳は脳のように分かれる/kabe_short.py（版2）
def short_six(T, S):
    tp = T(1, 0.0)   # 「でも、1時間に600回働くと」で、絵を暗くして紙を出す
    return vpage("成功率99%の<br>ロボット", (
        bg("src/bg/1時間に6回.jpg", 1920, -1180, 0, tp)
        + words([("成功率", WHITE), ("99%", GOLD), ("かなり優秀", WHITE)], T(0, 0.4), tp, 560, size=130, gap=1.2)
        + paper(grp(line("1時間に600回働くと", T(1, 0.6), size=44, weight=700)
                    + f'<div class="num" style="font-size:230px;line-height:1"><span id="c6">0</span>{land("回", T(1, 3.4), "font-size:96px")}</div>'
                    + line("人が駆けつける", T(1, 3.6), size=44, weight=700)
                    + card("fact", ink("10分に1回、呼ばれるロボット", T(2, 0.6), 0.05), T(2, 0.3), "店の人からすると", w=760), tp + 0.1), tp)
        + bigword("優秀？", T(3, 0.1), T(4, S(4) + 0.6), 640, size=250)
        + counter_js("c6", T(1, 2.4), T(1, 3.4), 6, dec=0) + shake_js([(T(3, 0.4), 0.3)])))


def short_oku(T, S):
    tp = T(1, 0.0)   # 「だから人に任せたんだよ」で紙を出す
    col = lambda a, b, t: (f'<div class="card k-fact" style="width:370px;opacity:0;animation:pop .45s ease-out {t:.3f}s forwards">'
                           f'<small>{a}</small><span class="serif" style="font-size:66px;font-weight:900;line-height:1.3">{b}</span></div>')
    return vpage("料理も、<br>僕が置きます", (
        bg("src/bg/最後の動作.jpg", 1920, -900, 0, tp)
        + words([("最後まで", WHITE), ("責任を持って", GOLD)], T(0, 2.6), tp, 560, size=120, gap=0.8)
        + bigword("ドテッ", T(0, S(0) + 0.05), tp, 820, size=200, rot=-10)
        + paper(grp(card("mi", ink("だから、人に任せた", T(1, 0.3), 0.06), T(1, 0.1), "エイイチ", w=600, anim="wipe")
                    + line("一番難しい所を、ロボットにやらせていない", T(2, 0.3), size=36, weight=700), tp + 0.1, T(3, 0.0))
                + grp(f'<div class="row2" style="gap:24px">{col("料理をテーブルに置く", "お客さん", T(3, 0.3))}{col("トレーに載せる", "店員さん", T(3, 2.4))}</div>'
                      + f'<div class="serif" style="font-size:46px;font-weight:700;margin-top:10px">{ink("頑張らない所を決めて、", T(4, 0.3), 0.06)}<br>{land("広がった", T(4, 2.2), "font-size:72px;font-weight:900")}</div>', T(3, 0.05)), tp)
        + shake_js([(T(0, S(0) + 0.35), 0.3)])))


def short_tobira(T, S):
    tp = T(2, 0.0)   # 「扉を通らない手があります」で紙を出す
    lab = lambda txt, t: f'<div style="{SANS}font-size:28px;font-weight:700;color:#5a564f;height:44px;text-align:center">{ink(txt, t, 0.05)}</div>'
    seg = lambda txt, bgc, fg, t: (f'<div class="seg" style="width:250px;background:{bgc};color:{fg};font-size:34px;clip-path:inset(0 100% 0 0);animation:wipe .45s ease-out {t:.3f}s forwards">{txt}</div>')
    return vpage("ロボットは、<br>扉を開けられない", (
        bg("src/bg/扉.jpg", 1920, -1900, 0, tp)
        + words([("夜から", WHITE), ("朝まで", GOLD), ("開けて……", WHITE)], T(0, 1.2), T(1, 0.0), 560, size=120, gap=1.6)
        + words([("扉は", WHITE), ("体当たりで", GOLD)], T(1, 0.6), tp, 600, size=130, gap=0.6)
        + bigword("ボツ", T(1, S(1) + 0.3), tp, 1100, size=200, rot=-12)
        + gon_words(tp)
        + paper(grp(line("扉を通らない手", T(2, 0.2), size=46, weight=900)
                    + '<div style="display:flex;width:750px">'
                    + f'<div style="width:250px">{lab("洗い場側", T(2, 1.4))}</div><div style="width:250px">{lab("両側から取れる棚", T(2, 2.2))}</div><div style="width:250px">{lab("客席側", T(2, 1.4))}</div></div>'
                    + '<div style="display:flex;width:750px">'
                    + seg("調理場", "#cfc8ba", "#22201c", T(2, 1.6)) + seg("棚", "#22201c", "#f5f3ee", T(2, 3.0)) + seg("ロボット", "#ece9e2", "#22201c", T(2, 5.0))
                    + '</div>'
                    + line("ロボットは、棚にトレーを置くだけ", T(2, 5.6), size=36, weight=700), tp + 0.1), tp)
        + shake_js([(T(1, S(1) + 0.6), 0.3)])))


# segs: (本編の文番号, 後ろの間[, 頭を切る秒, 字幕の文])
# big: 大きなハコブくんの出る間（end の文の頭で、左下の大きさへ）。kind: rise（下から飛び出す）/ hop（跳ねて喜ぶ）
SHORTS = [
    dict(no=1, name="成功率99パーセント", fn=short_six, lead=0.5,
         segs=[(0, 0.35), (1, 0.5, 0.0, "でも、1時間に600回働くと、｜1時間に6回、｜人が駆けつける｜ことになります。"), (2, 0.6), (3, 0.5), (4, 1.2, 0.0, "……僕も、｜自信が｜なくなってきました。")],
         big=dict(kind="dash", end=1),
         face=[(-1, 0.0, 5.5, "joy"), (1, 0.0, 6.0, "base"), (2, 0.0, 4.0, "surprise"), (3, 0.0, 2.0, "doubt"), (4, 0.0, 3.0, "trouble")],
         pose=[(-1, 0.0, 2), (1, 0.0, 1), (2, 0.0, 3), (3, 0.0, 3), (4, 0.6, 4)], ei_rise=None,
         se=[(-1, 0.0, "se_whoosh", -8), (0, 0.4, "se_pop", -10), (0, 1.6, "se_pop", -8), (0, 2.8, "se_pop", -10), (1, 3.4, "se_pop", -8), (3, 0.1, "se_pop", -6)]
            + [(1, 2.4 + 0.18 * k, "se_tick", -16) for k in range(6)]),
    dict(no=2, name="料理も僕が置きます", fn=short_oku, lead=0.4,
         segs=[(27, 0.6), (28, 0.5), (25, 0.35, 0.0, "しかも、一番難しい所を、｜ロボットに｜やらせていません。"), (26, 0.6), (29, 1.2, 0.95, "配膳ロボットは、頑張らない所を決めて、広がりました。")],
         big=dict(kind="fall", end=2, fall=(0, 4.9)),   # 「だから人に任せたんだよ」が終わるまで倒れたまま
         face=[(-1, 0.0, 4.9, "joy"), (0, 4.9, 3.8, "x"), (1, 0.0, 2.2, "trouble"), (4, 0.0, 3.5, "smile")],
         pose=[(-1, 0.0, 1), (0, 5.1, 3), (1, 0.0, 2), (2, 0.0, 1), (3, 0.0, 2), (4, 0.0, 4)], ei_rise=None,
         se=[(-1, 0.0, "se_rise", -8), (0, 2.6, "se_pop", -10), (0, 3.4, "se_pop", -8), (0, 4.9, "se_whoosh", -10), (0, 5.2, "se_pop", -6), (1, 0.0, "se_whoosh", -12)]),
    dict(no=3, name="扉は体当たり", fn=short_tobira, lead=0.5,
         segs=[(63, 0.4, 0.0, "ロボットがお店のフロントから｜バックヤードに行くには、｜扉を開けられない｜といけない。｜ここが今、目に見える問題かな。"), (64, 0.9), (66, 1.2, 0.66, "扉を通らない手があります。両側から取り出せる棚を客席側に置いて、ロボットはそこにトレーを置くだけにする。")],
         big=dict(kind="wall", end=2),
         face=[(-1, 0.0, 9.0, "x"), (1, 0.0, 3.4, "joy"), (1, 3.5, 1.2, "x"), (2, 0.0, 4.0, "base")],
         pose=[(-1, 0.0, 1), (0, 0.0, 2), (1, 0.0, 3), (1, 3.4, 4), (2, 0.0, 2)], ei_rise=None,
         se=[(-1, 0.0, "se_whoosh", -8), (0, 1.2, "se_pop", -10), (0, 2.8, "se_pop", -10), (0, 4.4, "se_pop", -8), (1, 0.6, "se_pop", -10), (1, 1.2, "se_pop", -8), (1, 3.6, "se_pop", -6), (2, 0.0, "se_whoosh", -12)]),
]


# ---- 2本目で足した大きなハコブくんの動き（2026-11-02 エイイチの指摘）----
# dash: 左右に何度も素早く行き来する（ショート1）/ fall: ボケのあと前のめりにコケる（ショート2）/ wall: 左の端の壁に何度もぶつかる（ショート3）
WALL_T0, WALL_PERIOD = 0.5, 0.95     # wall: 最初にぶつかるまでの準備と、1回の往復の秒


def wall_impacts(t_end):
    """wall の動きで、壁にぶつかる時刻の一覧"""
    out, t = [], WALL_T0 + WALL_PERIOD * 0.55
    while t < t_end - 0.2:
        out.append(round(t, 3)); t += WALL_PERIOD
    return out


def gon_words(t_end):
    """壁にぶつかるたびに「ゴン」を出す"""
    return "".join(
        f'<div class="big" style="left:40px;right:auto;top:{900 + (k % 3) * 70}px;font-size:120px;color:#fff;-webkit-text-stroke:8px #141311;paint-order:stroke fill;'
        f'text-shadow:0 10px 0 #c4472a;transform:rotate({-14 + (k % 2) * 8}deg);z-index:6"><span style="animation:boom .2s cubic-bezier(.2,1.8,.4,1) {t:.3f}s forwards, hide .15s linear {t + 0.45:.3f}s forwards">ゴン</span></div>'
        for k, t in enumerate(wall_impacts(t_end)))


def vpages10(text):
    """字幕の枚（1行10字・3行まで）。short_kit.wrap の折り方で"""
    out = []
    for part in text.split("｜"):
        if not part:
            continue
        ls = SK.wrap(part, SUB_MAXC)
        if ls is None:
            out.append(None); continue
        while ls:
            n = len(ls)
            k = 3 if n == 3 or n >= 5 else min(n, 2)
            out.append("\n".join(ls[:k])); ls = ls[k:]
    return out


def build(sh):
    idx_main = json.load(open("tts/index.json"))
    ei_main = set(K._ei_lines())
    lead = round(sh.get("lead", 0) * FPS)
    segs, t = [], lead
    for k, sg in enumerate(sh["segs"]):
        i, pause = sg[0], sg[1]
        trim = sg[2] if len(sg) > 2 else 0.0
        o = idx_main[i]
        dur = o["dur"] - trim
        frames = round((dur + pause) * FPS)
        segs.append(dict(k=k, i=i, trim=trim, text=sg[3] if len(sg) > 3 else o["text"], face=o.get("face", "base"),
                         start=t, speech=round(dur * FPS), frames=frames, ei=i in ei_main))
        t += frames
    total = t
    if total / FPS > 30.5:
        sys.exit(f"ショート{sh['no']} が {total / FPS:.1f}秒あります（30秒以内）")
    Tf = lambda k, off=0.0: (segs[k]["start"] / FPS if k >= 0 else 0.0) + off
    Sf = lambda k: segs[k]["speech"] / FPS
    html = sh["fn"](Tf, Sf)
    folder = f"ショート/{sh['no']:02d}_{sh['name']}"
    os.makedirs(folder + "/png", exist_ok=True)
    # --- 声 ---
    pcm = np.zeros(total * SR // FPS + SR, np.int16)
    for s in segs:
        with wave.open(f"tts/{s['i']:03d}.wav") as w:
            a = np.frombuffer(w.readframes(w.getnframes()), dtype=np.int16)
        a = a[int(s["trim"] * SR):][:s["frames"] * SR // FPS]
        if s["trim"]:
            a = (a * np.minimum(1, np.arange(len(a)) / (0.02 * SR))).astype(np.int16)   # 切った頭を短くなじませる
        s0 = s["start"] * SR // FPS
        pcm[s0:s0 + len(a)] = a
    pcm = pcm[:total * SR // FPS]
    # --- 字幕と紙の映像 ---
    from playwright.sync_api import sync_playwright
    SUBCSS = (f"*{{margin:0;padding:0}}html,body{{width:{W}px;height:{H}px;background:transparent}}svg{{position:absolute;left:0;top:0}}"
              f".t{{font-family:'Noto Sans CJK JP',sans-serif;font-size:{SK.SUB_FS}px;font-weight:800;fill:#fff;stroke:#0D0D0D;stroke-width:12px;stroke-linejoin:round;paint-order:stroke fill}}")
    subs = []
    with sync_playwright() as p:
        br = p.chromium.launch()
        pg = br.new_page(viewport={"width": W, "height": H})
        for s in segs:
            pages_ = vpages10(s["text"])
            n, tot, acc = len(pages_), sum(len(x or "") for x in pages_), 0
            for pk, ptxt in enumerate(pages_):
                if ptxt is None:
                    sys.exit(f"字幕が折れない: {s['text']}")
                svg = ''.join(f'<text x="{SUB_CX}" text-anchor="middle" class="t">{_html.escape(ln)}</text>' for ln in ptxt.split("\n"))
                pg.set_content(f'<!doctype html><html><head><meta charset="utf-8"><style>{SUBCSS}</style></head><body><svg width="{W}" height="{H}">{svg}</svg></body></html>')
                pg.evaluate(f"""() => {{ const ts=[...document.querySelectorAll('text.t')]; const n=ts.length; let fs={SK.SUB_FS};
                  for (const t of ts) {{ const w=t.getComputedTextLength(); if (w>{SK.SUB_MAXW}) fs=Math.min(fs, Math.floor({SK.SUB_FS}*{SK.SUB_MAXW}/w)); }}
                  ts.forEach((t,k)=>{{ t.style.fontSize=fs+'px'; t.setAttribute('y', Math.round({SUB_MID}+(k-(n-1)/2)*{SK.SUB_LH}+fs*0.36)); }}); }}""")
                path = f"{folder}/png/sub_{s['k']}_{pk}.png"
                pg.screenshot(path=path, omit_background=True)
                K.fill_holes(path)
                a = s["start"] + round(s["speech"] * acc / max(1, tot))
                acc += len(ptxt)
                b = s["start"] + (s["frames"] if pk == n - 1 else round(s["speech"] * acc / max(1, tot)))
                subs.append((a, b, K.sub_layer(path)))
        mp4 = f"{folder}/_paper.mp4"
        K.render_block(dict(name=sh["name"], html=html), total, mp4, pg)
        br.close()

    # --- ハコブくん: 全身。最初は大きく、本題で左下の大きさへ ---
    def full(hh):
        o = hk.Hakobu(mode="full")
        bb = o.body.getbbox()
        o.h = hh; o.w = round((bb[2] - bb[0]) * hh / (bb[3] - bb[1])); o._cache = {}
        return o
    hs, hb = full(HK_SMALL_H), full(HK_BIG_H)
    tline = [(s["start"], s["start"] + s["frames"], s["start"] + s["speech"], s["face"], not s["ei"]) for s in segs]
    if lead:
        tline = [(0, lead, lead, "base", False)] + tline
    mp = pcm.astype(np.float32) / 32768.0
    speak = np.zeros(total, bool); eispk = np.zeros(total, bool)
    for s in segs:
        a0, a1 = s["start"] * SR // FPS, (s["start"] + s["frames"]) * SR // FPS
        if s["ei"]:
            mp[a0:a1] = 0; eispk[s["start"]:s["start"] + s["speech"]] = True
        else:
            speak[s["start"]:s["start"] + s["speech"]] = True
    params = hs.animate(tline, mp)
    for k, a, d, f in sh["face"]:
        ex = hk.EXPR[f]
        for i in range(int(Tf(k, a) * FPS), min(total, int((Tf(k, a) + d) * FPS))):
            eyes, brows, mouth, ring, dy = params[i]
            if not speak[i]:
                mouth = ex["rest"]
            params[i] = (ex["eyes"], ex["brows"], mouth, ring, dy)
    t_end_big = Tf(sh["big"]["end"])
    SHR = 0.5   # 小さくなるのにかける秒

    def hk_place(t):
        """→ (高さ, 足もとの中心 x, 足もと y, 角度, 回す中心の横の割合)"""
        sx, sy = HK_X + hs.w / 2, FOOT
        kind = sh["big"]["kind"]
        big_h = 720 if kind == "fall" else HK_BIG_H
        bw = hb.w * big_h / HK_BIG_H
        pv = 0.5
        if t >= t_end_big + SHR:
            return HK_SMALL_H, sx, sy, 0.0, pv
        if kind == "rise":
            k = 1.15 * np.sin(min(1, t / 0.45) * np.pi / 2) if t < 0.45 else 1.0 + 0.15 * np.exp(-(t - 0.45) * 6) * np.cos((t - 0.45) * 14)
            bx, by = 540 + 40 * np.sin(t * 1.1), 1990 + (1900 - 1990) * k + 14 * np.sin(t * 2.2)
            rot = 6 * np.sin(t * 1.3)
        elif kind == "dash":   # 左右に何度も素早く行き来する。向きを変える所で少し止まって傾きが戻る
            per = 0.5
            ph = (t % per) / per
            leg = int(t // per) % 2
            u = ease(min(1, ph / 0.8))
            xl, xr = bw / 2 - 150, 1080 - bw / 2 + 110   # 左右の端から少しはみ出すまで走る（版1は幅が約240pxで動いて見えなかった）
            x0, x1 = (xl, xr) if leg == 0 else (xr, xl)
            bx = x0 + (x1 - x0) * u
            by = 1900 - 26 * abs(np.sin(ph * np.pi * 3))
            rot = (9 if leg == 0 else -9) * (1 - ease((ph - 0.8) / 0.2)) if ph > 0.8 else (9 if leg == 0 else -9) * min(1, ph / 0.12)
            if t < 0.25:
                by = 1990 + (by - 1990) * ease(t / 0.25)
        elif kind == "fall":   # 跳ねて喜んだあと、前のめりにコケる（回す中心は前の足もと）
            tf = Tf(*sh["big"]["fall"])
            bx, by = 260, 1900
            if t < tf:
                ph = (t * 1.9) % 1.0
                by = 1900 - 120 * 4 * ph * (1 - ph)
                rot = 6 * np.sin(t * 3.8)
                if t < 0.3:
                    by = 1920 + (by - 1920) * ease(t / 0.3)
            else:
                u = t - tf
                pv = 0.95
                rot = 86 * ease(u / 0.32) if u < 0.32 else 86 + 5 * np.exp(-(u - 0.32) * 8) * np.cos((u - 0.32) * 28)
        else:   # wall: 左の端の壁に、何度もぶつかる
            xw, xf = bw / 2 - 6, bw / 2 + 300
            if t < WALL_T0:
                bx, rot, by = xf, 0.0, 1990 + (1900 - 1990) * ease(t / WALL_T0)
            else:
                ph = ((t - WALL_T0) % WALL_PERIOD) / WALL_PERIOD
                by = 1900
                if ph < 0.55:   # 壁へ向かって速くなる
                    u = (ph / 0.55) ** 2
                    bx, rot = xf + (xw - xf) * u, -7 * u
                else:           # ぶつかって跳ね返る（はじめの一瞬は体が反る）
                    v = (ph - 0.55) / 0.45
                    bx = xw + (xf - xw) * ease(v)
                    rot = 14 * np.exp(-v * 5) * np.cos(v * 18)
                    by = 1900 - 40 * np.sin(min(1, v * 2) * np.pi)
        if t < t_end_big:
            return big_h, bx, by, rot, pv
        u = ease((t - t_end_big) / SHR)
        return big_h + (HK_SMALL_H - big_h) * u, bx + (sx - bx) * u, by + (sy - by) * u, rot * (1 - u), pv

    # --- エイイチ（全身・2倍） ---
    sprites = {}
    for k_, nm in EI_POSES.items():
        im = Image.open(f"src/ei/エイイチ_全身_{nm}_170px_v2.png").convert("RGBA")
        im = im.resize((round(im.width * EI_SCALE), round(im.height * EI_SCALE)), Image.NEAREST)
        # 暗い背景に服が沈むので、うすい光の縁を付ける（本編の暗い場面と同じ）
        from PIL import ImageFilter
        pad = 20
        g = Image.new("L", (im.width + 2 * pad, im.height + 2 * pad), 0)
        g.paste(im.split()[3], (pad, pad))
        g = g.filter(ImageFilter.GaussianBlur(7)).point(lambda v: int(min(255, v * 1.6) * 0.45))
        lay = Image.merge("RGBA", (Image.new("L", g.size, 235), Image.new("L", g.size, 232), Image.new("L", g.size, 225), g))
        lay.alpha_composite(im, (pad, pad))
        sprites[k_] = np.asarray(lay.crop((pad, 0, pad + im.width, pad + im.height))).astype(np.float32)
    ei_pcm = pcm.astype(np.float32) / 32768.0
    hop = SR // FPS
    rms = np.array([np.sqrt(np.mean(ei_pcm[i * hop:(i + 1) * hop] ** 2)) if eispk[i] else 0.0 for i in range(total)])
    ref = np.percentile(rms[rms > 0.01], 85) if (rms > 0.01).any() else 1.0
    bob = np.zeros(total, int)
    for i in range(0, total, 3):
        bob[i:i + 3] = -EI_SCALE if rms[i:i + 3].mean() > 0.45 * ref else 0
    poses = sorted((Tf(k, a), p_) for k, a, p_ in sh["pose"])

    def ei_dy(t):
        """ei_rise: その時刻まで画面の下に隠れていて、下から出てくる"""
        if not sh.get("ei_rise"):
            return 0
        t0 = Tf(*sh["ei_rise"])
        if t < t0:
            return 760
        return int(760 * (1 - ease((t - t0) / 0.35)))

    # --- 音 ---
    voice = pcm.astype(np.float32) / 32768.0
    ref_v = np.percentile(np.abs(voice[voice != 0]), 90) if (voice != 0).any() else 0.1
    raw = subprocess.run(["ffmpeg", "-v", "error", "-i", "sound/bgm_明るいB_2.mp3", "-ac", "1", "-ar", str(SR), "-f", "s16le", "-"], capture_output=True, check=True).stdout
    bgm = np.frombuffer(raw, np.int16).astype(np.float32) / 32768.0
    bgm = np.tile(bgm, int(np.ceil(len(voice) / len(bgm))) + 1)[:len(voice)]
    bgm *= ref_v / (np.percentile(np.abs(bgm), 90) + 1e-6) * 10 ** (-24 / 20)
    fade = np.ones(len(voice)); nfo = int(1.0 * SR); fade[-nfo:] = np.linspace(1, 0, nfo)
    mix = voice + bgm * fade
    se_list = list(sh["se"])
    if sh["big"]["kind"] == "dash":
        se_list += [(-1, 0.5 * k + 0.05, "se_whoosh", -16) for k in range(int(t_end_big / 0.5))]
    if sh["big"]["kind"] == "wall":
        se_list += [(-1, ti, "se_pop", -6) for ti in wall_impacts(t_end_big)]
    for k, off, name, lv in se_list:
        raw = subprocess.run(["ffmpeg", "-v", "error", "-i", os.path.join(K.BASE, "sound", name + ".wav"), "-ac", "1", "-ar", str(SR), "-f", "s16le", "-"], capture_output=True, check=True).stdout
        se = np.frombuffer(raw, np.int16).astype(np.float32) / 32768.0
        se *= ref_v / (np.abs(se).max() + 1e-6) * 10 ** (lv / 20)
        s0 = int(Tf(k, off) * SR)
        n = min(len(se), len(mix) - s0)
        if n > 0:
            mix[s0:s0 + n] += se[:n]
    mix *= 0.98 / max(0.98, np.abs(mix).max())
    K.write_wav(f"{folder}/_mix.wav", (mix * 32767).astype(np.int16))

    # --- 重ねる ---
    out = f"{folder}/ショート{sh['no']}_{sh['name']}_版1.mp4"
    enc = subprocess.Popen(["ffmpeg", "-v", "error", "-y", "-f", "rawvideo", "-pix_fmt", "rgb24", "-s", f"{W}x{H}", "-r", str(FPS), "-i", "-",
                            "-i", f"{folder}/_mix.wav", "-map", "0:v", "-map", "1:a", "-c:v", "libx264", "-preset", "medium", "-crf", "20", "-pix_fmt", "yuv420p",
                            "-af", "loudnorm=I=-14:TP=-1.5:LRA=11", "-c:a", "aac", "-b:a", "160k", "-ar", "48000", "-movflags", "+faststart",
                            "-frames:v", str(total), out], stdin=subprocess.PIPE)
    dec = subprocess.Popen(["ffmpeg", "-v", "error", "-i", mp4, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"], stdout=subprocess.PIPE)
    for f in range(total):
        t = f / FPS
        bgf = np.frombuffer(dec.stdout.read(W * H * 3), np.uint8).reshape(H, W, 3).copy()
        pose = 1
        for a, p_ in poses:
            if t >= a:
                pose = p_
        spr = sprites[pose]
        blend(bgf, spr, W - spr.shape[1] - 12, FOOT - spr.shape[0] + bob[f] + ei_dy(t))   # エイイチは右端に寄せる
        size, cx, fy, rot, pv = hk_place(t)
        img = (hb if size > HK_SMALL_H + 1 else hs).frame(params[f])
        if sh["big"]["kind"] == "wall" and t < t_end_big:
            # 壁にぶつかっている間は、壁（左）を向く。小さくなる所で、エイイチに向き合う右向きに戻る（2026-11-02 エイイチの指摘）
            img = img.transpose(Image.FLIP_LEFT_RIGHT)
            rot, pv = -rot, 1 - pv
        if abs(size - img.height) > 1:
            img = img.resize((round(img.width * size / img.height), round(size)), Image.LANCZOS)
        x, y = int(cx - img.width / 2), int(fy - img.height)
        if abs(rot) > 0.2:
            img, (ox, oy) = rotate_about(img, rot, (img.width * pv, img.height))
            x, y = x + ox, y + oy
        blend(bgf, np.asarray(img).astype(np.float32), x, y)
        for a, b, (sl, sx_, sy_) in subs:
            if a <= f < b:
                blend(bgf, sl, sx_, sy_)
        enc.stdin.write(bgf.tobytes())
    dec.stdout.close(); dec.wait()
    enc.stdin.close(); enc.wait()
    print(f"{out}  {total / FPS:.1f}秒")
    return out


if __name__ == "__main__":
    want = [int(a) for a in sys.argv[1:]] or [s["no"] for s in SHORTS]
    for sh in SHORTS:
        if sh["no"] in want:
            build(sh)
```

### ショート_タイトルと説明文.txt

```text
ショートのタイトルと説明文（本編「配膳ロボットが店に広がった理由は「賢さ」じゃなかった」から作った3本・版2）
関連動画には本編を設定してください。

━━━━━━━━━━━━━━━━
ショート1_成功率99パーセント
タイトル：
成功率99%のロボット、10分に1回呼ばれる #Shorts
説明文：
仮に成功率99%でも、1時間に600回働けば、1時間に6回は人が駆けつけることになる。店の人からすると、10分に1回呼ばれるロボット。それ、優秀なのかな。
成功率99%・1時間に600回は、X の議論の指摘をもとにした例の計算です（実在の機体の数字ではありません）。
マンガの絵は生成AI（Gemini）で作成しました。声は AI 音声です（エイイチの声も AI 音声で、本人の声ではありません）。
本編：配膳ロボットが店に広がった理由は「賢さ」じゃなかった
#配膳ロボット #フィジカルAI #ロボット

━━━━━━━━━━━━━━━━
ショート2_料理も僕が置きます
タイトル：
料理まで置こうとした配膳ロボットの末路 #Shorts
説明文：
配膳ロボットは、一番難しい所をロボットにやらせていません。料理をテーブルに置くのはお客さん、トレーに載せるのは店員さん。頑張らない所を決めて、店に広がりました。
マンガの絵は生成AI（Gemini）で作成しました。声は AI 音声です（エイイチの声も AI 音声で、本人の声ではありません）。
本編：配膳ロボットが店に広がった理由は「賢さ」じゃなかった
#配膳ロボット #飲食店 #ロボット

━━━━━━━━━━━━━━━━
ショート3_扉は体当たり
タイトル：
配膳ロボットは扉を開けられない。体当たりは、ボツ #Shorts
説明文：
下げ膳で洗い場まで行くには、調理場の扉が壁になる。決まりで求められているのは調理場と客席の仕切りで、形は地域の決まりや保健所の判断で変わります。そこで、両側から取り出せる棚を客席側に置き、ロボットはトレーを置くだけにする手があります。
店に入れるときは、地域の保健所に確かめてください。
マンガの絵は生成AI（Gemini）で作成しました。声は AI 音声です（エイイチの声も AI 音声で、本人の声ではありません）。
本編：配膳ロボットが店に広がった理由は「賢さ」じゃなかった
#配膳ロボット #飲食店 #ロボット
```

### ショートの書き出しのログ（python3 kabe_short.py 1 / 2 / 3 の出力）

```text
== short_log1.txt
  成功率99パーセント: 704コマ（撮影 223）
ショート/01_成功率99パーセント/ショート1_成功率99パーセント_版1.mp4  23.5秒
== short_log2.txt
  料理も僕が置きます: 691コマ（撮影 221）
ショート/02_料理も僕が置きます/ショート2_料理も僕が置きます_版1.mp4  23.0秒
== short_log3.txt
  扉は体当たり: 663コマ（撮影 385）
ショート/03_扉は体当たり/ショート3_扉は体当たり_版1.mp4  22.1秒
```
