# 雪 — Style Reference
> 深い緑黒の夜に、遠くは細かく速度の遅い雪、手前は大きくボケた雪がゆっくり落ちる。山影の中に小屋の灯りが1つ。

**Theme:** dark  **Series:** PARTS 037  **World:** 標高の高い山小屋。冬も灯りをつけて開いている。

## Concept
ヒーロー背景の1パーツ。主役は奥行きのある雪で、1粒ごとに「層」の値(0 遠い〜1 近い)を持ち、層で落下速度・横揺れ・大きさ・ボケ・透明度が変わる。
粒子の位置は種と時間から頂点シェーダーで決める(状態を持たない GPU 粒子)。風はゆっくり変わり、カーソルや指を横に動かすと一時的に吹く。背景は空の勾配と2層の山影、小屋の灯り1つ。

## Signature Technique
WebGL1、2つのプログラム(背景の全画面三角形 + `gl.POINTS` の雪)。外部ライブラリなし。

- 粒子: COUNT(desktop 2600 / mobile 900)。属性 `a = (seedX, seedY, layer)`、`layer = random^2.3`(遠い層ほど多い)。
- 頂点シェーダー:
  - 速度 `sp = mix(.045, .26, L²)·FALL`、横揺れ `sw = mix(.004, .022, L)`
  - `y = fract(seedY - t·sp)`、`x = fract(seedX + t·sp·wind·(.5+L) + gust·(.3+L) + sway)`、sway は2つの sin。位相は `ph = hash(seed)·2π` で 0〜2π に収める(`seedX·50` のような大きな引数を sin に渡すと GPU によって量子化され、雪が縦の列に並ぶ)
  - 大きさ `gl_PointSize = mix(FAR_SIZE 2, NEAR_SIZE 34, L³)·(高さ/900)`
  - 明るさのばらつき `vA = .6 + .4·hash`
  - 灯りの照り返し `vW = exp(-|p - LIGHT_POS|·mix(7, 3.5, L))·(.5 + .5L)`(画面比補正込み)。灯りの近くの雪だけが暖色を拾う
- フラグメント: `d = |gl_PointCoord - .5|·2`、ボケ `soft = mix(.25, .95, L)`、`a = (1 - smoothstep(1-soft, 1, d))·mix(.95, .2, L)·vA`。近いほど大きく薄くボケる。近い粒は `a *= 1 + .35·L·smoothstep(.45,.9,d)` で縁をわずかに明るくし、レンズのボケの輪を出す。色は `mix(SNOW, LIGHT·1.15, min(vW,.85))`。
- 合成: 背景を描いた後、premultiplied alpha(`ONE, ONE_MINUS_SRC_ALPHA`)で雪を重ねる。
- 風: `wind = WIND·(.6·sin(.11t) + .4·sin(.043t+1))`。突風は pointermove の x 移動量 × GUST を積み、`0.15^dt` で減衰、粒子には `dt·2.5` の lerp で届く。
- 背景: 空 `mix(SKY_LOW, SKY_TOP, smoothstep(0,.75,y))`。山影は 1D value noise の稜線2本(`.20 + .10n(1.6x) + .05n(4.2x) + .02n(11x)` と `.11 + ...`)。灯りは `smoothstep(.006,.002,d)` の点、`.25·exp(-22d)` の滲み、`.06·exp(-5d)` の広い暈、3Hz で僅かに揺れる。
- 解像度: `min(devicePixelRatio, 2)`(mobile 1.5)。点の大きさは高さ基準で補正。

## Color Palette
| Token | HEX | 役割 |
|---|---|---|
| --night | #0B1512 | html背景 |
| SKY_TOP | #09120F | 空の上 |
| SKY_LOW | #2B2126 | 地平線の空(薄い珊瑚の残光) |
| ridge-far | #0D1614 | 遠い山影 |
| ridge-near | #080D0D | 近い山影 |
| SNOW | #F5F2EB | 雪 |
| LIGHT | #FF8C6B | 小屋の灯り |
| --snow | #F3F1EC | 見出し・ロゴ・pill 枠 |
| lead | #C6CCC8 | 本文 |
| --fog | #8A948F | ラベル・フッター |
| --coral | #F4706B | CTA の点だけ |

## Typography
- 見出し: Zen Kaku Gothic New 300、`clamp(34px, 5.4vw, 78px)`、line-height 1.28、letter-spacing .02em、`<br>` で2行固定。
- 本文: Zen Kaku Gothic New 300、`clamp(14px, 1.15vw, 17px)`、line-height 1.9、最大 32em。
- ラベル(.mono): DM Mono 400/500、12px(mobile 11px)、letter-spacing .1em、大文字。
- ボタン: 500、14px、letter-spacing .06em。左に珊瑚の点(7px、光つき)。

## Spacing & Layout
- 1画面 = `100svh`、`grid-template-rows: auto 1fr auto`。本文は左寄せ・垂直中央、最大幅 760px、下余白 10vh(山影と重ねない)。
- 左右余白 `clamp(20px, 5vw, 72px)`、上 28px、下 22px(+safe-area)。
- 山影は画面下 20〜35%。灯りは x 66%、y 13.5%。
- breakpoint 640px: 見出し `clamp(30px, 8.4vw, 40px)`、フッター2行積み。

## Motion
- 近い層は 4 秒ほどで画面を落ち、遠い層は 20 秒以上。
- 風は 60〜150 秒周期で向きが変わる。突風は 1 秒ほどで消える。
- requestAnimationFrame 1本。`visibilitychange` と IntersectionObserver で画面外は停止。
- `prefers-reduced-motion`: t=40 の静止フレームを1回描く。
- WebGL 非対応: radial-gradient の点4つと空の linear-gradient。

## Components
- hero: 全画面。上に小屋名と分類、中央左に eyebrow / h1 / lead / CTA。
- button(.cta): 高さ46px の pill。雪色の1px枠に透明の地で、左に珊瑚の点。hover で雪色の地に夜色の文字。focus-visible は雪色のリング。
- footer(.bot): 等幅、左に操作説明、右に `VALE / PARTS 037 / 雪`。
- section: このパーツには無い。

## Do / Don't
- Do: 近い層は大きく薄くボケさせる。奥行きはボケで出る。
- Do: 遠い層を多くする(`random^2.3`)。
- Do: 灯りは1つ。その周りの雪だけ暖色にして、光が雪に当たっている瞬間を作る。
- Don't: 雪を白い点だけにしない。層の差が無いと壁紙に見える。
- Don't: ミントや蛍光緑のアクセントを置かない。
- Don't: 粒子を増やしすぎない。2600 で十分。

## References
- Tableland: 深い緑黒の虚空に柔らかな峰、信号灯1つという構図を抽象化。ミントの信号灯は珊瑚の小屋の灯りに替えた。
- Kippo: 黒地に等幅のラベル、細い白の輪郭だけの UI を抽象化。ピンクのアクセントは CTA の点1つに絞った。

## Usage
1. `<canvas id="gl">` と `<script>` ブロック全体を切り出す。`.still` と `#hint` も一緒に。
2. canvas は `position:fixed; inset:0`。上に載せる要素は `position:relative; z-index:1`。
3. パラメータは JS 冒頭の `P`:
   - `SCALE` 描画解像度倍率
   - `COUNT` 雪の数、`FALL` 落ちる速さ
   - `WIND` 常風の強さ、`GUST` カーソルの突風(0で無効)
   - `NEAR_SIZE` `FAR_SIZE` 近い層と遠い層の直径(px)
   - `SNOW` `SKY_TOP` `SKY_LOW` `LIGHT` の4色
   - `LIGHT_POS` 灯りの位置(x は画面幅比、y は下から)。雪の照り返しもこの位置を中心にする
4. 背景を自分のサイトの色にするなら `bg` プログラムの描画を外し、canvas を `alpha:true` にして雪だけ重ねる(blend は premultiplied のまま)。
5. 山影を消すなら bgFS の r1/r2 の2行を削る。灯りの位置は bgFS の `lp` と `P.LIGHT_POS` を揃える。
6. 雨にするなら NEAR_SIZE を 3、`sp` を 4 倍、点を縦長にする(フラグメントで `gl_PointCoord.x` を強く減衰)。
