# パンくず — Style Reference
> 夜の森の床に、読者が落としたパンくずだけが暖色で点り、鳥が一粒ずつ食べていく

**Theme:** dark  **Series:** FABLE 003  **World:** グリム童話『ヘンゼルとグレーテル』。夜の森、落ち葉と苔、パンくず、鳥、森の奥の砂糖の家。

## Concept
スクロールで歩く絵本。読み進めた分だけ、画面の下のほうにパンくずが落ちる(文書座標に固定されるので、上へ戻ると自分の歩いた道が見える)。放っておくと鳥の群れが来て一粒ずつ食べ、戻れる道は短くなる。残ったパンくずを押すと、その場所へスクロールで戻れる。パンくずが文字通りのナビゲーションで、消えることが物語の筋と一致する。
色は暗い緑黒の森にパンくずの暖色1つ。終盤だけ照明と色が変わり、Three.js の砂糖の家が暖かい窓灯りで現れる(区画ごとに照明と登場物を変える構成)。
開いた瞬間に伝えること: 「これはヘンゼルとグレーテルの絵本で、スクロールが歩くこと」。見出し1本+短文1〜2文を上限にし、余白で粒を見せる。

## Signature Technique
1. **パンくず粒子(2D canvas, 文書座標)**
   - 粒 = `{x, y(doc), r, rot, a, born, claim}`。描画時に `y - scrollY` で画面座標へ。画面外±40pxは描かない。
   - 落とす条件: (a) 初期の道 34粒(モバイル26)を 45ms 間隔で上から画面の 74% 高さまで、(b) スクロール 26px ごとに `pathX(docY) = W*(.5 + .3 sin(docY*.0032) + .08 sin(docY*.0113))` に1粒、(c) デスクトップはカーソルが22px動くごとに1粒、(d) 「森」「鳥」の区画が画面の85%まで入った瞬間に、その区画の文書座標へ24粒(モバイル16)の道を一度に敷く。森は文字の反対側(右)、鳥は左。上から入ってきた読者が、どこで画面を止めても道が見える。上限 600粒(モバイル320)、古い順に消す。
   - 見た目: 24px の不規則5〜7角形スプライト5種(線形グラデ #f6d59a→#e2b063→#9c6a25、ハイライト1点)+ 64px の放射グローを 44r で重ねる。生成直後は 0.25s でフェードイン。
   - 押すと戻る: `click` で半径18px以内の粒を探し `scrollTo(y - H*.62)`。
2. **鳥 = boids + 状態機械(hunt / peck / roam / leave)**
   - 速度上限 210px/s(モバイル170)、操舵力 700。分離は半径40px、群れ行動(結合0.9 / 整列1.2)は roam 中のみ半径180px。
   - hunt: 画面内で生後1.6s以上かつ他の鳥が claim していない最寄りの粒へ seek、70px 以内で減速、7px で着地して peck へ。peck は 0.9〜1.5s、頭を `max(0, sin(phase))*0.32s` だけ前へ突き出し、突くたびに粒を 0.8 倍に削って 3つの欠片(#e9b86a 1〜2.6px、0.5〜0.9s で消える)を散らす。半径 0.45 未満で食べ終わり。
   - 鳥の区画に入ると、敷いた道の上に 6羽(モバイル4)を peck 状態で置き、くちばしの先が粒に来る位置に向ける。4粒に1粒は先に食べられた状態にして、道の欠けを最初から見せる。
   - 鳥の座標も文書座標。地面に降りた鳥はスクロールで粒と一緒に流れる。
   - 粒が無くなると roam(ランダムウォーク+群れ)、4〜7s で leave(画面外へ出たら削除)。出現数 = `min(13, 2 + ceil(可視粒/5))`、0.5〜1.0s に1羽ずつ端から。
   - 描画は上から見たシルエット: 胴の楕円(0.62s×0.36s、s=28px、モバイル18)+扇形の尾+頭の円+黄土色のくちばし、羽は `quadraticCurveTo` で 2枚、羽の見かけ長 `0.45 + 0.55|cos(phase)|`(phase += 17 rad/s)。6px右12px下に黒32%の影を同形で描き、浮いて見せる。目は #efc277 の小点2つ。縁は rgba(200,212,202,.62) 1.1px で暗い床から浮かせる。
3. **森の床(CSS img + hard-light シェーダー)**
   - `assets/forest.webp` を fixed の `<img>`(高さ 100%+720px、`brightness(.5) saturate(.85)`)に置き、スクロール×0.16 で視差。
   - その上の WebGL フルスクリーン三角形を `mix-blend-mode: hard-light` で合成。0.5 が中立。`light = exp(-5.5 r²)` の月明かりを +0.22、fbm 4オクターブ(モバイル3)の霧を `+(.09,.12,.11) f (.35 + uFog .8)(.3 + .7 light)`、周辺減光 -0.26、粒状ノイズ ±0.015。
   - `uLight` はデスクトップでカーソルへ 0.04/フレームで追従、タッチ端末ではリサージュで漂う。`uFog` は「森」区画が画面中央にあるとき 1。file:// では画像を WebGL テクスチャに渡せないため、この合成方式にした。
4. **砂糖の家(Three.js r170)**
   - 壁: `MeshStandardMaterial` #7b4a2a roughness .94、bumpMap は http 時 `assets/sugar.webp`(repeat 2.2)、file:// 時は 256px 値ノイズ fbm(周波数90)。bumpScale .08。
   - 屋根の砂糖衣: `MeshPhysicalMaterial` #eadcdd roughness .62、bumpMap = 値ノイズ fbm(周波数40, repeat 3, bumpScale .12)、sheen 1 (#ffc4d6)、clearcoat .2。屋根板は三角柱の屋根裏に法線方向 +0.06 で乗せる(勾配 atan2(0.85, 0.95))。屋根裏の三角柱は妻面を ±x に向け、棟を x 方向へ通す(屋根板と同じ向き)。
   - キャンディ: 球 r .10〜.17 を屋根面上に配置。`transmission .88, thickness .5, roughness .1, ior 1.45, iridescence .9, iridescenceIOR 1.3, iridescenceThicknessRange [120,420], attenuationDistance .7, clearcoat .4`。色 5種(#ff8fb8 #8ff0d2 #ffe27a #8fd0ff #ffb07a)。
   - 窓: 壁面すぐ前の発光板 #ff9a3c に、厚さ .02 の飴ガラス(`transmission 1, thickness .08, roughness .18, ior 1.5, iridescence .6, clearcoat 1`)を重ね、灯りが飴越しに透ける。
   - 地面のグミ: 半球、transmission .85 thickness .6 roughness .32 + attenuation(自色, .5)、iridescence .6、clearcoat .8、ごく弱いノイズ bump。キャンディケーン: CatmullRom を TubeGeometry、縞は 64×16 の canvas テクスチャ。
   - 照明: 環境 RoomEnvironment(強度 .25)、月 DirectionalLight #a9c0d8 1.6(影 1024, デスクトップのみ)、戸口の PointLight #ffa85a 6(開扉時 10)+室内 2.5、揺らぎ `1 + .05 sin(9.3t) + .03 sin(23.7t)`。地面は ShadowMaterial(.45)と放射グラデの光だまり。
   - カメラ: fov 30、z 9.6(700px未満は 15.5。家と飴の杖が画面の幅に収まる)。`rotY = -.95 + prog*.55 + mouseX*.35`、`camY = 2.1 - prog*.55 - mouseY*.35` を 0.06/フレームで追従。prog は区画の画面内進行度。デスクトップは家を x=+2.5 にずらし、左に文字を置く。
   - 「戸を開ける」ボタンで扉ピボットを -1.75rad、灯りを強める。区画が画面外のときは描画しない。

```js
// 鳥の seek(抜粋)
const d=Math.hypot(dx,dy)||1, sp=d<70?SP*Math.max(.25,d/70):SP;
ax+=(dx/d*sp-b.vx)*FO/SP; ay+=(dy/d*sp-b.vy)*FO/SP;
if(d<7){ crumb.eaten=true; b.state='peck'; b.t=.3+Math.random()*.25; }
```

## Color Palette
| Token | HEX | Role |
|---|---|---|
| --bg | #070b09 | 画面全体の地。緑を含む近黒 |
| --fog | #26352c | 霧の色(シェーダー内は .09/.12/.11 の加算) |
| --fg | #e8e3d8 | 見出し・本文。暖かい骨白 |
| --mute | #8f968c | 小ラベル、フッター |
| sub text | #b3b8ad | 本文(サブ) |
| --crumb | #efc277 | パンくず、計測値の数字、focus ring、スクロール合図。唯一の暖色アクセント |
| --crumb2 | #b9842e | パンくずの影側 |
| gingerbread | #7b4a2a | 家の壁 |
| frosting | #eadcdd | 屋根の砂糖衣 |
| window light | #ffa85a | 窓と戸口の光 |
| candy | #ff8fb8 / #8ff0d2 / #ffe27a / #8fd0ff | 屋根のキャンディ。家の区画だけに出す |

## Typography
- 見出し: Shippori Mincho 700。h1 `clamp(64px, 10vw, 152px)` line-height 1、letter-spacing .06em(モバイル `clamp(56px, 20vw, 120px)`)。h2 `clamp(28px, 3.6vw, 52px)` line-height 1.3、letter-spacing .04em。
- 本文: Zen Kaku Gothic New 300、`clamp(14px, 1.1vw, 16px)`、line-height 1.9、最大幅 30em。補足は 12.5px。
- ラベル: IBM Plex Mono 400 11px。英字は大文字 + letter-spacing .12em、日本語ラベルは .08em。計測値は `clamp(26px, 3vw, 40px)` tabular-nums。
- ワードマーク「パンくず」は Shippori Mincho 500 15px、letter-spacing .2em。
- 全文字に `text-shadow: 0 1px 14px rgba(7,11,9,.55)` を敷いて霧の上でも読めるようにする。

## Spacing & Layout
- 横余白 `--gx: clamp(20px, 5.5vw, 84px)`。区画は `min-height: 100svh`、上下 `clamp(72px, 12vh, 140px)`。
- 内容幅 1200px、文字ブロック 520px(家の区画は 440px、家はデスクトップで x=+2.5 に寄せて文字と重ねない)。区画ごとに左/右へ寄せ、片側を空ける。森の区画は左寄せにし、鳥の区画は右寄せにし、家の区画は左下に寄せる。
- hero は3行グリッド(空/本文/脚注)。本文は下寄せ、上半分はパンくずの道のために空ける。
- 家の区画は canvas を absolute 全面、文字は下寄せ、下 60%(モバイル 75%)に地色のグラデを敷く。
- 締めは `min-height: 70svh` 中央寄せ。footer は 1px の罫線と2つの小ラベル。
- breakpoint 640px: スクロール合図を消す、脚注を縦積み、右寄せ区画を左寄せに。700px 未満で家を中央・カメラを遠ざける。

## Motion
- パンくずと鳥の canvas は本文の下(z-index 2、本文 3)。粒が見出しの上に乗らない。
- rAF は1本(`window.__pankuzu.add(fn)`)。`visibilitychange` で停止、家の区画は IntersectionObserver で画面外なら描画しない。
- パンくずは 0.25s で現れ、食べられると 0.3s で縮んで消える。鳥は 17rad/s で羽ばたき、ついばみ中は遅くなる。
- 月明かりの追従 0.04/フレーム、家の回転・カメラ 0.06/フレーム、扉 0.08/フレーム。すべて一次遅れで、イージング関数は使わない。
- スクロール合図は 2.4s 周期で 1px の線を落とす(cubic-bezier(.6,0,.4,1))。
- `prefers-reduced-motion: reduce`: 初期の道を一度に置き、鳥は出さない。霧と月明かりは時間 0 で固定、家は固定アングルで1枚描画。スクロールに応じた再描画のみ残す。
- WebGL が無い場合: 2つの canvas を消し、forest.webp はそのまま背景に残し、hero に1行の説明を出す。

## Components
- hero: 左上ワードマーク、右上 `Fable 003`。下部に英字ラベル、h1、2文、脚注(操作説明)と「下へ」の合図。
- section: 日本語1文字のラベル(森・鳥・家のいずれか)と h2 とサブ1〜2文。鳥の区画だけ3つの計測値(落とした/食べられた/森にいる鳥)を実測で表示。
- house: 3D canvas + 下寄せの文字ブロック + 操作ヒント(タッチ端末では文言を差し替え)。
- button: 角丸999px、1px の骨白枠、hover で反転。focus-visible は --crumb 2px。「戸を開ける」→「戸を閉める」にトグル。
- footer: `VALE / FABLE 003` と `設計と実装: VALE`。

## Do / Don't
- Do: 暖色はパンくず(と窓灯り)だけに限る。色を増やすと粒が見えなくなる。
- Do: 粒は文書座標に置く。戻ったとき自分の道が残っている/消えていることが筋そのもの。
- Do: 鳥は粒が置かれてから 1.6s 待たせる。先に道を見せてから食べさせる。
- Do: 家の区画は文字を片側に寄せ、家は反対側へ。重ねない。
- Don't: 紫のグラデや背景の格子を足さない。森は写真+霧+月明かりだけ。
- Don't: 粒を装飾として自動散布しない。落ちる理由(スクロール、カーソル、初期の道)を必ず持たせる。
- Don't: 家にテキストやロゴの板を貼らない。質感(透過・虹彩・砂糖のバンプ)で見せる。

## References
- Discord: 「区画ごとに自前の照明と登場物を持つ環境として作る」構成を借りた。夜空の青と大型3Dキャラクターの代わりに、森の床の写真と鳥・パンくずを置き、終盤の家だけ暖色の照明に切り替えた。字組みの太い全大文字は使わず、明朝の見出しに置き換えた。
- Dovetail: 「ほぼ無彩色の暗い地に、1色だけを機能的な印として配る」配色の考え方を借りた。藍の代わりにパンの暖色を使い、その色をパンくず・計測値・focus ring だけに限定した。設計図の格子は使わない。
