# 雲の上まで — Style Reference
> 空色の一枚地に、三本撚りの豆の蔓。スクロールで畑から雲を抜け、雲海の上の城まで登る。

**Theme:** light  **Series:** FABLE 008  **World:** ジャックと豆の木(英国民話)。一晩で伸びた蔓を登ると、雲の上に巨人の城がある。

## Concept
ページ全体が一本の蔓。固定された WebGL canvas の中でカメラが蔓に沿って上昇し、スクロール位置がそのまま高度になる(0 m → 2,400 m。右下に常時表示)。地面(畑の土)→ 雲の中(白)→ 雲の上(濃い青と雲海)→ 城の輪郭、と光の状態が3段階で変わる。
主役は二つ。Catmull-Rom スプライン沿いに生成した三本撚りのチューブ(蔓)と、深度合成したレイマーチの体積雲。文章は左に1画面1見出し+一文だけ置き、右側を蔓が通る。配色は空色の地に黒インクの文字を置き、蔓の緑と雲の白を加える。ボタンは黒い丸薬形が1つ。

## Signature Technique
three.js r170(WebGL2)。シーンを `WebGLRenderTarget`(カラー + `DepthTexture`)に描き、全画面の合成パスで空と体積雲を深度に合わせて重ねる。RAF 1本。

蔓
- 主曲線: y を 0→300(1 unit = 8 m)で 45 点、x/z は `2.2 sin(0.055y+0.7) + 0.9 sin(0.17y+2.1)` などの重ね合わせで蛇行。`CatmullRomCurve3(centripetal 0.5)`。
- 三本撚り: 主曲線の Frenet frame(600 分割)を取り、`θ = 2πk/3 + t·46` で法線・従法線方向に半径 0.44(上端で 0.65 倍)だけずらした点列を各ステム用の `CatmullRomCurve3` にし、`TubeGeometry(1100 分割, 半径 0.34, 9 角)` を 3 本作る。
- テーパー: 生成後に各リングを曲線上の中心点へ `1 − 0.55t` で縮める。頂点属性 `aT`(0..1)を持たせる。
- 成長: `grow = min(1, prog·1.04 + 0.075)`(カメラより少し先)。`geometry.setDrawRange(0, floor(grow·1100)·9·6)` で先端まで描き、各ステムの `getPointAt(grow)` に芽(縦長の球)を置いて開口を隠す。
- シェーダー: 高さ 30 以上で `sin(0.55t + 0.09y)·0.22 + sin(1.1t + 0.23y)·0.07` の揺れ。色は `aT` で深緑 (0.19,0.46,0.22) → 黄緑 (0.47,0.76,0.30)。縦の筋 `0.86 + 0.14 sin(u·2π·4 + v·60)`。ラップ拡散 `nl·0.6+0.4`、空色のフレネル、弱いハイライト。

葉
- `InstancedMesh` 820 枚(スマホ 520)。1×1.45 の平面を根元原点に平行移動。各葉は 3 本のステムのどれかの `t` に置き、接線に直交する外向きベクトル(上下に −0.15〜+0.35 の傾き)を up にして `setFromUnitVectors`、さらに Y 回りに ±0.6 rad、X 回りに ±0.3 rad。スケール 0.7〜1.45。
- インスタンス属性 `aT`(位置)と `aPhase`。頂点シェーダーで `g = smoothstep(aT−0.015, aT+0.012, uGrow)`、スケール `g(1 + 0.3 sin(πg))` で開く。葉先ほど大きく揺れる。
- フラグメントで葉形: `w = 0.5·sin(πv)^0.62·(1 − 0.25v)`、`|u| > w` は discard。主脈と側脈は暗く。両面、裏側は法線反転。太陽が葉の裏にあるとき `pow(max(dot(−v, sun),0),6)·0.35` の透過光。

雲(合成パス)
- 雲層は y ∈ [106, 160](850〜1,280 m)の平板。03(1,200 m)では雲の中、04(1,600 m)では雲の上に出て、青空と雲海が写る。城の輪郭は高度 1,570 m から 1,740 m の間に不透明度 0→1 で現れ、05 で初めて見える。画素ごとに視線と平板の交点 t0/t1 を解析的に求め、交差しない画素は何もしない。内側にいるときは最長 220、外からは入口から 420 まで。
- 歩数 40(スマホ 26)、光方向 3 歩。`hash12(gl_FragCoord)·dt·0.35` でジッタ。
- 密度: 3D value noise を 256² の RG テクスチャ 2 回参照で評価(iq 方式。G は (37,17) ずらし)。`fbm3(p·0.024 + 風)`、高さプロファイル `smoothstep(0,0.2,h)·smoothstep(1.05,0.5,h)`、`smoothstep(0.49, 0.75, n·hp·1.35)`、細部は `noise(q·5.3)` で削る。蔓の周り半径 22〜64 には下地密度 0.55 を足し(蔓の真上は必ず雲)、カメラ距離+1.6 の内側は密度 0(握っている蔓が見える)。
- 光: Henyey-Greenstein g=0.3 ×2.6 + 0.12、光方向の 3 歩で `exp(−Σρ·6.9·0.55)` の自己遮蔽、`powder = 1 − exp(−2.2ρ)`。環境光は下面 (0.86,0.90,0.96) → 上面 (0.99,0.995,1.0)。`a = 1 − exp(−ρ·dt·0.95)` で前から積算、透過率 0.015 で打ち切り。
- 空: 天頂/地平の 2 色をカメラ高度 `above = smoothstep(CB+10, CT+12, camY)` で切り替える(下: 0.33,0.66,0.94 / 0.81,0.90,0.97 → 上: 0.14,0.42,0.84 / 0.64,0.81,0.95)。太陽は `pow(max(dot(rd,sun),0),48)`。雲の上では全体を ×1.08。
- 深度合成: `viewZ = (n·f)/((f−n)·z − f)`、`tScene = viewZ / rdView.z`。シーン画素は距離で `1 − exp(−t·0.0034)` だけ地平色に寄せ(大気遠近)、雲は `tScene` で止める。

カメラ
- `prog` はセクションに合わせた区分線形: 各セクションの中心が画面中央に来たとき、ちょうどそのラベルの高度(0, 400, … 2,400 m)になる。スマホとデスクトップで段組みの高さが違っても高度と見出しがずれない。
- `camY = 1.1 + prog·296.5`、蔓の中心点から距離 7.6(スマホ 9.6)で軌道角 `0.9 + prog·1.6`。注視点は中心 + 右方向 3.8(スマホ 2.5)で蔓を右 3 分の 1 に置く。仰角は 3.8 → 3.4 → 頂上手前(0.66〜0.84)で −2.2(城を見下ろす)→ 最後(0.88〜1.0)で +2.8(先端を見上げる)。
- 城はセクション 05 のカメラ(prog 0.83)から前方 240、左 34 に、雲頂 −4 の高さで置く。箱と円柱と円錐の `MeshBasicMaterial`(#1C2E4E)だけで、大気遠近で輪郭になる。
- スクロール追従は `1 − exp(−dt·6.5)` の時間基準補間。

## Color Palette
| Token | HEX | Role |
|---|---|---|
| --sky | #5CB0F0 | ページ地、読み込み前と WebGL 不可時の地 |
| --sky-deep | #2B6FD0 | 雲の上の天頂(シェーダー側は (0.14,0.42,0.84)) |
| --haze | #CFE6F8 | 地平の霞、遠景の蔓と城が寄る色 |
| --ink | #0C1A2B | すべての文字、ラベル罫、黒い丸薬ボタン、城 |
| --ink-soft | rgba(12,26,43,.62) | 英字ラベルとヒント |
| --leaf | #3FA34D | 葉の中間色(シェーダーは (0.24,0.56,0.28)〜(0.56,0.86,0.36)) |
| vine | (0.19,0.46,0.22)→(0.47,0.76,0.30) | 蔓。根元が深く先端が明るい |
| bud | #8FD45A | 成長先端の芽 |
| --cloud | #FFFFFF | 雲の最明部 |
| --line | rgba(12,26,43,.22) | フッターの罫 |

## Typography
- 見出し・本文とも Zen Kaku Gothic New。ウェイトは 500(h1/h2)と 400(本文)の 2 つだけ。階層はサイズで作る。
- h1 `clamp(72px,13vw,190px)` 行間 1 字間 .02em、1 行固定(nowrap)。h2 `clamp(36px,4.6vw,62px)` 行間 1.2。
- 本文 `clamp(16px,1.35vw,20px)` 行間 1.9、最大 30 字。
- ラベル・ヒント・高度表示は Geist Mono 400。ラベル 11px 字間 .14em 大文字(日本語部分は大文字化なし、字間 .12em)。高度の数字 `clamp(36px,4.4vw,64px)` 字間 −.02em、tabular-nums。単位 m は .42em。
- スマホ: h1 `clamp(50px,14.6vw,96px)`(ヒーローの本文は幅 72vw まで、蔓に重ねない)、h2 `clamp(30px,8.6vw,42px)`、本文 15px、高度 30px。

## Spacing & Layout
- セクションは `min-height:100svh` で縦中央に左寄せ。内側余白 `12vh 7vw`(スマホ `14vh 20px 16vh`、文章は下寄せ)。
- 文章ブロック最大幅 720px。1 画面に見出し 1 本 + 一文(hero のみ 2 文)。
- ヘッダー 28px(スマホ 20px)の固定余白。高度表示は右下 28px、フッターは右に 240px(スマホ 150px)空けて高度表示と重ねない。
- hero / 01〜05 / 締め の 7 画面 = 2,400 m。400 m ごとに 1 画面。
- breakpoint: 640px。

## Motion
- RAF 1 本。蔓と葉の揺れ、雲の風(`time·0.012`)、スクロール補間、描画をすべて同じフレームで更新。タブ非表示で停止。
- スクロール連動はカメラ高度と軌道角と仰角、それに蔓の成長範囲と空の色と高度の数字。それ以外の演出は置かない。
- 葉は成長範囲に入った瞬間 `1 + 0.3 sin(πg)` で一度ふくらんで開く。
- `prefers-reduced-motion`: 揺れと風を止め、時間を固定、補間なしでスクロール位置に追従、スクロール/リサイズ時だけ描画。
- WebGL2 不可: canvas を隠し、縦の空色グラデーション地で文章だけ読める。左下に一行で案内。

## Components
- hero: ラベル(ジャックと豆の木 — 一晩で伸びた蔓)+ h1「雲の上まで」+ 2 文 + 縦罫つきの「スクロールで登る」。ヒントは 3% スクロールで消える。
- section: 番号ラベル + 高度(01 — 畑の上 400 m … 05 — 頂上 2,000 m)+ h2 + 一文。
- altitude: 右下固定。`Altitude` ラベルと数字。0 m では透明、60 m で不透明。
- button: 黒い丸薬形 `16px 28px`、白文字 15px 字間 .08em、右に小さな山形。hover でわずかに明るく 1px 浮く。focus-visible は白 2px の outline。
- footer: 上罫 1 本、左に 2 行 `VALE / FABLE 008` と `Jack and the Beanstalk`。

## Do / Don't
Do
- 色は空色・白・緑・黒インクの 4 系統で止める。彩度の高い色は蔓と芽だけ。
- 雲は必ず深度と合成する。蔓の前後関係が崩れると偽物に見える。
- 文章は 1 画面に見出し 1 本。蔓の通り道(右 3 分の 1)に本文を置かない。
- 高度の数字は実際のカメラ位置から出す。セクションの表記と必ず合わせる。
Don't
- 雲や蔓を画像で置かない。地面の土だけが画像。
- 地面の土は ShaderMaterial で明るめに持ち上げ(pow .8、×(1.55, 1.38, 1.05))、カメラからの距離で地平線の霞 #CFE2F2 に溶かす(`1 − exp(−(d·.026)^1.25)`)。画面下端を黒い帯にしない。
- 紫や黒の地、グリッド線、浮遊する図形を足さない。
- 葉を増やして密度で誤魔化さない。影と透過光で見せる。
- 城を近づけない。輪郭が読める距離(240 unit)で霞ませたまま置く。

## References
- clau.as.kee: 一枚の飽和した地色の上に巨大な文字を 1 つ置き、UI は小さな文字と細い罫だけ、ウェイトを 1 つに絞って階層はサイズで作る、という骨格を抽象化した。ペリウィンクルの平面は空色の 3D 空間に、黒い文字彫刻は「雲の上まで」の 5 文字にし、緑の丸バッジは置かず、代わりに蔓の緑が唯一の彩度になるようにした。
- xAI: 温かい白地に文字が先導し、塗りのボタンは黒い丸薬形 1 つだけ、技術的な声はモノスペースで分ける、という役割分担を抽象化した。クリーム地は空色に、Geist Mono は高度表示と番号ラベルに当て、黒い丸薬ボタンはページ末尾の「根元へ戻る」1 か所だけに残した。
