01
尺
喋って初めて長さがわかる。
二十分の枠に三十分ぶん。
気づくのは前日の夜。
dek sample 2026.09.25 12 min
dek は、喋る台本を先に書き、そこからスライドを組み立てる道具です。この資料は発表のスライドであり、そのまま読める配布資料でもあります。
テンプレートを選び、枠を並べ、中身を埋め、最後に喋ってみる。この順番だと、確かめる機会はすべて最後の一歩に集まります。
いつもの順番
01
喋って初めて長さがわかる。
二十分の枠に三十分ぶん。
気づくのは前日の夜。
02
はみ出し、読めない色は、目で探すしかない。
見落としは、
本番のスクリーンで見つかる。
03
作り込んだ部品は、そのトークでしか使えない。
次はまた、
ゼロから作る。
順番を入れ替えます。台本を書いた時点で尺がわかり、画面はそのあとに組み立て、見た目は機械が測ります。
dek の順番
1
script.md
2 もう後回しにしない
dekc ls
3
slides/*.html
4 もう後回しにしない
dekc lint --visual
台本から決まるもの
台本がいちばん上にある。スライド側で決めることは、見た目だけ。
数字はこの資料の script.md から(dekc ls why-dek)。
dek では、ひとつの発表をデッキと呼び、ひとつのディレクトリにまとめます。
デッキの外にあるものは、何も参照しない。リモートの URL も、../ で親を指す道も lint が止めます。ディレクトリごとコピーすれば、何年後に開いても同じように描画されます。
decks/why-dek/
構成と数は、この資料 sample/decks/why-dek の実物(slides/ と assets/ のファイル数)。
覚える書き方は三つだけです。
script.mdこの資料の冒頭から抜粋--- title: 台本から、発表まで … duration: 12m 持ち時間 --- ## 台本から、発表まで {#cover} スライド cover こんにちは。今日は、dek というスライドの道具を紹介します。… 喋る言葉 > 落ち着いて始める。目次は読み上げない。 ト書き ## いまのスライド作りでは、三つのことが後回しになる {#later} スライド later … ### 尺 {#later-time} ビート later-time ひとつめは尺です。喋って初めて長さがわかるので、…
台本を保存すると、見出しごとに骨格ができます。見出しがタイトルに、ビートが箇条書きになります。どの行がどのビートで出るかも、最初から決まっています。
保存した直後骨格のまま、通しで練習できる
slides/later.html dekc sync が書いた 8 行。枚数、順番、尺は本番と同じ。
仕上げた後仕上げても、台本は変わらない
HTML 37 行 と CSS 106 行 を書いた。script.md は一文字も変えていない。
左はこの資料の写しから later.html を消して dekc sync、右はこの資料の later.html を、どちらも dekc shot で撮影。
仕上げの単位は一枚です。直すときに開くのは同じ名前の数ファイルだけなので、差分がそのまま読め、書き間違えても崩れるのはその一枚だけです。
slides/ の行数htmlcssts
この資料の slides/*.html・*.css・*.ts を wc -l で数えたもの(このスライド自身も含む)。
段階的に見せる仕組みも、役割を分けています。スライドの HTML は、要素がどのビートで出るかを data-step で書くだけです。
script.md いつ
### いつは、台本のビート {#beats-when} いつ出すかは、喋りの都合です。… ### どうは、テーマの CSS {#beats-how} どう出すかは、見せ方の都合です。…
slides/beats.html 結ぶ
<span class="bracket is-when" data-step="beats-when"> <strong>いつ:台本が決める</strong>… </span> <span class="bracket is-how" data-step="beats-how"> <strong>どう:テーマが決める</strong>… </span>
theme.css どう
.slide.is-current [data-step] {
opacity: 0;
transform: translateY(var(--rise));
transition: … var(--step-transition);
}
.slide.is-current [data-step].is-shown {
opacity: 1;
transform: none;
}
三つの抜粋は、このスライドとこの資料の theme.css の実物。
CSS で書けない動きは slides/<id>.ts に書きます。約束はひとつ。経過時間 t を受け取って、その瞬間の画面を描くこと。
slides/motion.ts抜粋const MS = 1200; function paint(frame: Element, t: number) { // t だけから棒の高さを決める … } export default { motion: { "0": MS }, draw(slide, { t }) { for (const frame of frames(slide)) { paint(frame, Number(frame.dataset.t)); } const live = slide.querySelector("[data-live]"); if (live) paint(live, t); }, } satisfies DekSlide;
同じ t を渡せば、必ず同じ画面になる
左の三枚は data-t の値で、右端は再生中の t で、同じ paint() が描いている。
台本があれば、尺はその場で見積もれます。十二分の持ち時間は、各スライドの文章量に応じて割り振られます。
引用はト書きなので数えない。速さは dek.toml で変えられる。
この資料の見積もり
11:28/ 12:00
スライド見積もり / 割り当て
見積もり持ち時間から割り当てた尺
bunx dekc ls why-dek --json(2026-09-25、script.md 確定版)の estimateSeconds と budgetSeconds。
見た目の確認も、目に頼りません。dekc lint --visual は、スライドを実際のブラウザで描画し、すべてのビートで測って、答えを数字で返します。
DEK030はみ出しは、何ピクセルかまで
{
"id": "DEK030",
"data": {
"box": "p.lede[data-step=\"slow\"]",
"text": "https://example.com/docs/…",
"edges": { "right": 41 },
"origin": "content",
"steps": ["slow", "vague"]
},
"hint": "shorten it, or let it wrap …"
}
DEK031読みにくい色は、比で返す
1.5: 1
基準 4.5 : 1
大きな文字は 3 : 1
24px・太字 18.66px〜
{
"id": "DEK031",
"data": {
"box": "p.faint[data-step=\"vague\"]",
"text": "補足:この注釈は薄すぎて読めません",
"ratio": 1.5,
"threshold": 4.5,
"fg": "#c8c4ba",
"bg": "#f3f1ec",
"origin": "slide",
"steps": ["vague"]
}
}
捨てデッキに dekc lint --visual --json をかけた実際の出力から、id と data を抜粋(severity・message・path・slug・hint は省略)。
使ってよいクラス、トークン経由の値、デッキの中の画像。書いておくだけでは守られない規約を、dek はすべてルールにしました。エラーがひとつもなければ完成です。
39ルール 五つの層
構造14
台本と slides/ の対応
語彙11
テーマの言葉だけで書いているか
素材4
デッキの中で閉じているか
描画5
ブラウザで描いて測る
音声5
読み上げと尺
エラー:完成を止める警告:報告するが、止めない
src/core/diagnostic.ts の RULES 表(39 件)を、docs/reference/lint.md の条件で五つの層に分けたもの。
完成の基準がはっきりしているので、AI エージェントも人と同じ手順で、一枚ずつ仕上げられます。
測ると直すの往復は、人が画面を確かめる前に片付く。
1一枚ぶんを、まとめて読む
$ dekc show why-dek timing
| script | 台本のその節 | 8 行 |
|---|---|---|
| html | slides/timing.html | 42 行 |
| css | slides/timing.css | 171 行 |
| ts | slides/timing.ts | 32 行 |
| theme | このスライドが使う規則だけ | 220 行 / 全体 518 行 |
2描いて、測って、直す
$ dekc check objection --shot --json捨てデッキ{ "ok": false, "slug": "objection", "diagnostics": [{ "id": "DEK030", "hint": "shorten it, or let it wrap with overflow-wrap: …", "data": { "edges": { "right": 41 }, "steps": ["slow", "vague"] } }, { "id": "DEK031", … }], "shot": ".cache/shots/objection~vague.b5ae5c96.png" }
直して、もう一度{ "ok": true, "slug": "objection", "diagnostics": [] }
行数は dekc show why-dek timing --json の各部の行数。JSON は dekc check の実際の出力の抜粋。
dekc ref は、GitHub に公開されている dek のデッキを、版を固定して手元に取ってきます。取ってきたデッキは読むだけ。使いたい部分は、自分のテーマで書き直します。
1 公開されているデッキ
GitHub
hajimism/dek/why-dek
owner/repo/deck の名前で指す。
2 版を固定する
dek.toml
[refs] "…/why-dek" = "<commit>"
版はコミットで止まる。動かすときは、もう一度 dekc ref。
3 読み取り専用で置く
refs/
lsshowthemeshot
gitignore される写し。消しても、次に読むとき取り直す。
4 自分のデッキ
decks/
自分のテーマで書き直して取り込む。ref を指す道は、デッキの外なので DEK022。
できること構成と尺を見る。一枚の作りを読む。描画して確かめる。
しないことref を書き換える。自分のデッキから ref を参照する。lint も build も refs/ を見ない。
使い方docs/guide/structure.md より$ bunx dekc ref hajimism/dek/why-dek
$ bunx dekc show hajimism/dek/why-dek timing
新しいデッキを作ると、プロジェクトのテーマがそのデッキにコピーされます。共有ではなくコピーなので、秋にテーマを直しても、春に話したデッキの見た目は変わりません。
変わらない終わった発表は、終わったときの姿のまま残る。
戻すときは手でcp decks/2026-09-dek/theme.css theme.css
dekc build が、テーマも画像も動きも含めて、発表をひとつの HTML ファイルにまとめます。会場にサーバもネットワークも要りません。
dist/why-dek.html
322KiB
同じファイルから
ブラウザで開けば、そのまま発表できる。
open dist/why-dek.html
台本、次のビート、経過時間。二つ目の窓がついてくる。
?presenter または p キー
同じ台本から
一枚一ページ、すべてのビートを出した姿で。
dekc pdf
音声合成で台本を読み上げ、ビートに合わせて記録する。
dekc video
bunx dekc build why-dek が書いた dist/why-dek.html の実測 330,127 バイト(2026-10-01)。
プロジェクトを作り、台本を書き、開発サーバを立ち上げる。配るときは build。
最初は骨格のままで構わない。通しで喋れるようになってから、必要なスライドだけを仕上げる。
必要なものBun1.4 以降。ほかは dek が入れる。
コマンドは docs/guide/getting-started.md より(一部省略)。
最後に、三つだけ持ち帰ってください。
順番も、喋る言葉も、尺も、台本が持っている。スライドはそこから生まれる。
→ 順番 台本 尺
一枚ずつの HTML と、隣の CSS と TS。人もエージェントも、一枚ずつ直せる。
→ ファイル ビート エージェント
規約はすべて lint が確かめる。この資料も、診断ゼロで出来上がっている。
→ 測る lint
この資料そのものが、上の三つで作られています。台本は右下のファイルに。