# 泡になる前に — Style Reference
> 海面の光を見上げる青から始まり、スクロールで200 mまで沈む。文章は泡の中にあり、最後は文字が泡になって昇り、画面が白くなる。

**Theme:** dark  **Series:** FABLE 002  **World:** アンデルセン「人魚姫」。海面から深海へ、最後は泡。

## Concept
縦スクロールが水深計になっているサイト。右端に0〜200 mの目盛と現在の水深(整数m)が固定表示され、スクロール位置に連動する。
主役はヒーローの「海面の光」。ボロノイ系ノイズで作るコースティクス(水面で屈折した光の網)と、それを太陽方向へ放射状ブラーした光の帯。下へ行くほど光は3乗で減り、青は紺から黒へ寄り、ビネットが締まって圧を出す。
文章は4つの「泡」(円形のガラス)の中にだけ置く。各泡が1水深(10/30/80/150 m)に対応し、人魚姫の原作の事実(声を渡す、刃の痛み、300年の命)と海の事実(赤い光の消失、9気圧)だけを短く書く。
200 mで題名「泡になる前に」が点の集まりになり、スクロールで泡として上へ昇り、背景が白に抜ける。白は人魚姫が朝の光の中で泡になった場面。締めは「もう一度、海面から。」と上へ戻るボタン1つ。

## Signature Technique
全画面固定の WebGL キャンバス1枚(webgl2優先、webgl1フォールバック)。ライブラリなし。requestAnimationFrame 1本で4パス。

1. コースティクス(半解像度FBO, RGBA8)
   - Voronoi: 3×3セル走査、セル点を `0.5+0.5*sin(t+6.2831*hash)` で揺らす。エッジ量 `e = sqrt(F2)-sqrt(F1)`。
   - 線 `l = pow(clamp(1-e*k,0,1), 9)`(k=1.9 / 2.1)。2層(スケール比1.73、別速度)を `0.42*la + 0.24*lb + 1.7*la*lb` で合成。交点だけが強く光る。
   - 見上げ視点: `persp = 1/(1.35-0.75*uv.y)` で上ほど細かく。入力座標に `0.22*vec2(sin(q.y*1.3+t*.21), cos(q.x*1.1-t*.17))` のドメインワープを足し、多角形の硬さを消す。
2. 水の合成(フル解像度)
   - 深さ `d`(0..1 = 0..200 m を lerp 0.09 で平滑化)。光量 `light = (1-d)^3`。
   - 色は上下2点の勾配を深さで3段階補間(表層 #125E80/#052B4D → 中層 #05213D/#020E1F → 深層 #010711/#000205)。
   - 光の帯: 太陽点 `(0.5, 1.25)` へ向けてコースティクス texture を18タップ放射サンプリング(重み 0.88^i)。距離減衰 `smoothstep(1.9,0.2,dist)`。
   - 海面写真(1枚、data URI、1100px webp)は `light` で消える素材。輝度の高い所だけ `1+max(lum-.35,0)*0.6*light` で持ち上げる。
   - マリンスノー: 64px セルに hash で点、深いほど見える。ビネット `1-dot(q,q)*(0.55+d)`。IGN ディザ 1.8/255 でバンディング防止。
   - 白: `mix(col, #F3F7F9 - 薄いコースティクス, uWhite)`。
3. 泡(GPGPU)
   - 位置テクスチャ 22×22(mobile 14×14)、RGBA32F(なければ RGBA16F / OES_texture_float / CPU更新にフォールバック)。各テクセル = (x, y, 半径r, 位相)。
   - 更新: `y += (0.035+0.16*r^2 + scrollV*(0.35+0.5*r))*dt`。scrollV はスクロール速度(vh/s, 0.6倍, 減衰 0.02^dt)。下スクロールで泡が速く昇り、上スクロールで上から降りてくる。
   - 横揺れ `sin(t*(0.9+ph*2.2)+ph*6.28)`。カーソルから `smoothstep(0.22,0,dist)` の反発。範囲外で下端に再生成。
   - 描画: gl.POINTS、サイズ `(1.8+r*20)*dpr*(1-0.3d)`、リング+ハイライト、小さい泡は点。加算ブレンド(SRC_ALPHA, ONE)。深いほど薄く、白では消える。
4. 文字→泡
   - 最終セクションの h2 をオフスクリーン canvas に同じフォント・サイズで描き、2.6px 格子(mobile 2.2px)で alpha>90 の点を拾う(約3,000〜5,000点)。座標は h2 の矩形からの相対で持ち、毎フレーム `getBoundingClientRect` の原点を足す(stickyで動くため)。
   - 進行 `p`(sticky区間 0..1)。点ごとの開始ずらし `t = clamp(p*1.75 - seed*0.75, 0, 1)`、上昇 `t^2*(0.42+0.75*seed)*vh`、横揺れ、サイズ 2.6→最大17px。t≥0.55で消える。点→リング(泡)へ形も変わる。
   - 白化は `p` の 0.58〜1.0 を smoothstep。水深計もこの区間で 200 → 0 m へ戻る。

## Color Palette
| Token | HEX | 役割 |
|---|---|---|
| --surface | #1A6E8C | 海面付近の水(上端)。シェーダー表層 #125E80 |
| --deep | #06243D | html 背景・中層の水 |
| --abyss | #010610 | 200 m の水。最深部と 200 m 区間の地 |
| --ink | #E6F1F6 | 見出し・本文(泡の中) |
| --ink-2 | rgba(214,232,242,.80) | 本文の補助 |
| --mute | rgba(170,206,226,.62) | ラベル(モノスペース)、ヒント |
| --rim | rgba(190,226,246,.24) | 泡の縁 1px、ハイライト |
| light | rgb(148,219,250) | コースティクスと光の帯の色(加算) |
| --white | #F3F7F9 | 最後の白。薄いコースティクスを引いて #E8EEF3 程度の網 |
| --navy | #0B2238 | 白画面の文字・ボタン線 |

## Typography
- 和文: Shippori Mincho 400/500/600(Google Fonts)。`font-feature-settings:"palt"`。
- h1(題名): 500、`clamp(46px, 8.4vw, 116px)`、letter-spacing .14em、text-indent .14em で中央合わせ、text-shadow 0 2px 40px rgba(1,6,16,.55)。
- 泡の h2: 600、`clamp(24px, 3.3vw, 40px)`、letter-spacing .08em、line-height 1.3。mobile `clamp(22px, 6.4vw, 26px)`。
- 本文: 400、`clamp(14px, 1.1vw, 16.5px)`、line-height 2、letter-spacing .05em、max-width 21em。改行は `<br>` で固定し1文1行。
- ラベル・水深: IBM Plex Mono 400、11px、letter-spacing .14em。水深の数字は 22px(mobile 18px) tabular-nums、単位 m は 11px。
- 締め h2: 500、`clamp(28px, 4vw, 50px)`、letter-spacing .1em、nowrap(420px以下で解除)。
- ボタン: 14px、letter-spacing .14em。

## Spacing & Layout
- 左右余白 `--pad: clamp(20px, 5vw, 72px)`。ブランド表記は左上(mobileでは非表示)、水深計は右端 `--pad - 6px`、上下 16vh。
- hero: 100svh、grid-template-rows 1fr auto auto。題名は下 1/3、上 2/3 を光に渡す。
- station: min-height 100svh + 上下 18vh。泡は `--w: min(560px, 78vw)`(mobile `min(89vw, 372px)`)、padding は `calc(var(--w)*.13)`(%指定は親幅基準になるので使わない)。
- final: 230svh、内側 100svh を sticky。end: 100svh、本文 max-width 34em。footer は左右2点。
- breakpoint 640px(泡・水深計・ブランド)、420px(締め h2 の改行)。

## Motion
- 水: Voronoi の時間項 0.42〜0.55 rad/s、流れ 0.03〜0.05 uv/s。1周期が十数秒。
- 深さ・白の追従: lerp 0.09 / 0.12。スクロール速度: 0.5 で平滑化、80ms 無入力で `0.02^dt` 減衰。
- 泡の CSS: translate 0→-14px の 9s/11s ease-in-out。圧の泡は 60→120 m で scale 1→0.94。
- 文字→泡: 題名の区間の上端が画面の上 1/4 に入った時点で自動で始まる。時間曲線 `autoCurve(t)`: 0〜1.2 秒で進行 0.18 まで ease-out(下から崩れ始め、上の点が泡になって昇る)、1.2〜5.6 秒は 0.18→0.23 とほぼ止めて「文字が泡になりかけた」状態を見せ、5.6〜10 秒で smoothstep で 1 まで。進行は `max(スクロール量, 時間)` で、スクロールで先へ進められる。区間から出ると時間は 0 に戻る。
- reduced-motion: 時間を t=4 で固定、GPGPU更新停止、文字の点描をやめて DOM の題名を `opacity: 1 - p/0.7` で消す。スクロール時のみ1フレーム再描画。
- WebGL なし: `.nogl` で CSS の縦グラデーション(海面→深海)、ヒーローに1行の説明、end/footer は白地。
- `visibilitychange` で停止・再開。リサイズは 120ms デバウンスで FBO と文字点を再構築。

## Components
- hero: ラベル「海面 / 0 m」、h1、1文、「スクロールで潜る」+ 48px の落ちる縦線。
- 水深計(.gauge): 1px の縦罫、10 m ごとの 6px 目盛、50 m ごとに 12px。現在位置に 56px の横線と数字。白化後は navy に反転。
- 泡(.orb): 円。縁 1px、左上に斜めのハイライト(楕円、blur 1.5px)、右下に conic-gradient の細い光弧(mask で 1.5px 幅)、backdrop-filter blur 1.5px。中はラベル / h2 / 本文。
- 締め: ラベル「海面 / 朝」、1文、h2、pill ボタン(navy 線、hover で反転、focus-visible は --surface のリング)。本文と注記は `word-break: auto-phrase` で文節の途中で折り返さない。注記の文字は navy の 64%。
- footer: `VALE / FABLE 002` と題名を左右に。

## Do / Don't
Do
- 色は青の階調だけで組む。光は加算で足し、彩度の高い別色を置かない。
- 1画面に置くのは泡1つと見出し1本。文は2行まで。
- 数字は事実(水深、気圧、300年)だけを置き、水深計の値と文中の値を一致させる。
- 深さに応じて光・泡の量・ビネットを同時に落とし、「圧が増す」を言葉より画面で伝える。
- 白は最後の1回だけ。

Don't
- 泡を増やして画面を埋めない(4096個で壁紙化した。484個で十分)。
- コースティクスを白飛びさせない(交点だけを強く、線は弱く)。
- 泡の padding を % で書かない(親幅基準で文字が折れる)。
- 画像を主役にしない。写真は 40 m で消える素材。
- 泡に本文以外の装飾(アイコン、罫線)を足さない。

## References
- Langbase(stock/refero/md/langbase.md): 「色は一箇所だけ、あとは無彩色のヘアライン」「数字と開発者的な識別はモノスペース」を抽象化。ここでは唯一の色を"海面の光"に、ヘアラインを水深計に、モノスペースを水深の数字に置き換えた。配色は青の階調に変更。
- Factory(stock/refero/md/factory.md): 「黒い地に明るいカードを1枚だけ置く」図/地の強さを抽象化。カードをガラスの泡に変え、縁1pxとハイライトで立たせた。アクセントの橙と緑は使わず、白への反転を最後の1回に限定した。
