# アトラクター — Style Reference
> 紺の闇に、ローレンツの2枚の翼が白い粒で浮かぶ

**Theme:** dark  **Series:** PARTS 033  **World:** 架空の気象アンサンブル研究所「Yoho」のトップ。わずかな初期値の差が結果を分けることを、粒子の軌道そのもので見せる。

## Concept
画面中央に粒子の塊を1つ。粒子はそれぞれがローレンツ方程式の解で、GPU 上で毎フレーム積分されている。定常状態では2つの翼の形に広がり、クリックで同じ初期値(ばらつき 0.08)から撒き直すと、最初は1本の線だった粒子が数秒で翼全体に散らばる。色はクリーム1色、速い粒子だけ橙。右上に係数 σ・ρ・β と経過時間 t の読み出し。

## Signature Technique
GPGPU で常微分方程式を粒子ごとに RK4 積分し、軌跡バッファに加算する。

1. **位置テクスチャ**: 一辺 `side`(256、モバイル 128)の RGBA float。`xyz`=系の座標、`w`=直前の速さ。WebGL2 は `RGBA32F`(不可なら `RGBA16F`)、WebGL1 は `OES_texture_float`。
2. **積分**(`SIM_FS`): 1 フレームに `sub=3` 回、刻み `h=0.0035` の RK4。
   ```glsl
   vec3 f(vec3 p){ return vec3(sigma*(p.y-p.x), p.x*(rho-p.z)-p.y, p.x*p.y-beta*p.z); }
   k1=f(p); k2=f(p+.5h*k1); k3=f(p+.5h*k2); k4=f(p+h*k3);
   d=(k1+2k2+2k3+k4)/6;  p+=h*d;  speed=length(d);
   ```
   係数は σ=10、ρ=28、β=8/3 で固定。1 フレームで t が 0.0105 進む(60fps で 0.63/秒)。
3. **初期値**: 起動時は系の全域(x±20、y±25、z 0–50)に一様に散らし、240 ステップ回して過渡状態を飛ばす。クリック時は `(-8, 8, 27)` の周りに正規分布(σ=0.08)で置き直し、t を 0 に戻す。
4. **描画**: 系の座標から中心 `(0,0,25)` を引いて 1/21 に縮め、`(x, z, -y)` に並べ替えて z を上にする。`R = Rx(pitch)·Ry(yaw)` で回し、`xy·focal/(cam−z)` で透視投影。奥は alpha 0.3 まで落とす。速さ 30→150 でクリーム→橙。点は半径 0.25〜0.5 で縁をぼかした円、`gl_PointSize = size·cam/z`。
5. **軌跡**: 画面解像度の RGBA8 FBO を2枚。`max(prev − 0.004, 0)·0.86` で前フレームを薄め、粒子を `ONE / ONE` で加算。約 10 フレームの短い尾が付き、動きの向きが見える。
6. **操作**: カーソル位置で yaw(2.3±0.6)と pitch(0.1±0.35)の目標値が動き、毎秒 3 の一次遅れで追う。ドラッグで回し、動かさずに離すと撒き直し(タッチも同じ)。
7. IntersectionObserver と visibilitychange で画面外停止。リサイズで軌跡 FBO だけ作り直す。

## Color Palette
| Token | HEX | Role |
|---|---|---|
| --void | #10161f | 地。表示シェーダーの背景色も同じ |
| --cream | #fffaea | 粒子、見出し、ブランド名、クレジット |
| --bone | #d9d5c8 | 本文 |
| --zinc | #7c8089 | ヘッダーのラベル、操作説明 |
| --iron | #2a313b | 予備の罫線色(未使用) |
| --ember | #ff6a2b | 速い粒子、経過時間の数字。面には使わない |

## Typography
- 日本語見出し: Noto Sans JP 400、`clamp(20px, 1.8vw, 26px)`、letter-spacing −0.01em、line-height 1.45。太らせない。
- 本文: Noto Sans JP 300、`clamp(13px, 1.05vw, 15px)`、最大幅 30em(761px以上は 37em)。`word-break: auto-phrase` と `text-wrap: pretty` で文節の途中で折り返さない。デスクトップで2行に収める。粒子数は JS で実測を書き込む。
- ラベル: JetBrains Mono 400、11–12px、letter-spacing 0.06–0.08em。ギリシャ文字の係数もそのまま等幅で置く。
- WebGL 不可時は `.fallback` にブランド名を Inter 300 の大きな字で出す。

## Spacing & Layout
- hero `min-height: 100svh`、3行グリッド。canvas は背面全面。
- 余白: 横 `clamp(20px, 5vw, 72px)`、縦 `clamp(20px, 3vw, 40px)`。モバイル左右 18px。
- 翼は画面中央。縦長画面では焦点距離を `min(2.2, 0.62·aspect·cam)` に縮め、中心を上へ 0.2(横長画面は 0.03)ずらす。
- breakpoint 760px: ブランド横の説明を消し、読み出しの間隔を詰め、フッターを縦積み。

## Motion
- 初期姿勢 yaw 2.3、pitch 0.1。自動回転 0.08 rad/s。カーソルで yaw ±0.6、pitch ±0.35 rad。ドラッグは x 1.8、y 1.2 倍、pitch は ±0.9 で止める。
- 積分は固定刻みで、フレームレートに関わらず 1 フレームに t が 0.0105 進む。
- 撒き直し後、1本の線が翼に広がるまで t≈6(約 10 秒)。
- `prefers-reduced-motion: reduce`: rAF を回さず、420 ステップ進めてから1枚描く。翼の静止画になる。クリックでの撒き直しは1枚だけ再描画する。

## Components
- hero: 背面 canvas(`aria-hidden`、`cursor: crosshair`)+前面テキスト。テキスト層は `pointer-events: none`。
- header: 左にブランド名、右に `σ 10 · ρ 28 · β 8/3` と `t 12.4`(橙)。
- copy: 見出し1行+本文2文。
- footer tag: `VALE / PARTS 033 / アトラクター` と操作説明1行(タッチ端末では文言差し替え)。

## Do / Don't
- Do: 視点は yaw≈2.3(y軸まわり)から。翼が2枚とも見える。yaw 0 付近は翼が重なって V 字に見える。
- Do: 起動時の初期値は系の全域に散らす。1点から始めると最初の数秒が線にしか見えない。
- Do: 撒き直しのばらつきは 0.05–0.2。0 だと全粒子が同じ軌道を辿り、分かれない。
- Don't: 1粒の明るさを 0.2 以上にしない。翼の中心が白飛びする。
- Don't: 軌跡を長くしない(fade 0.95 以上)。翼が面になり、粒子の動きが消える。
- Don't: 係数を変えて別の形にしない。σ=10 ρ=28 β=8/3 で翼になる。

## References
- Pally: 紺の闇に骨白の文字を置き、色は製品の中だけという構造を借りた。製品の紫の代わりに、粒子の速さを示す橙を1点だけ置いた。
- Vapi: 深い闇に暖色クリームの細い文字、角の立った等幅ラベルで技術的に見せる考え方を借りた。スペクトログラムの代わりに微分方程式の軌道を置いた。

## Usage
1. `<canvas id="gl">` を hero の背面に置く。フォントは任意。
2. `<script>` ブロック全体を移植する。`boot()` が粒子テクスチャと軌跡 FBO を作り、240 ステップ回してから描き始める。
3. 系を差し替える: `SIM_FS` の `f(vec3 p)` を別の常微分方程式(Rössler、Aizawa 等)にし、`P.center` / `P.scale` / `P.hot` を系の寸法に合わせる。
4. 色は `ink` / `acc` / `bg` を CSS 変数と揃える。
5. 読み出し(`#t`、`#n`)が不要なら、その行を消す。撒き直しが不要なら `reseed()` の呼び出しを消す。

| パラメータ | 既定 | 意味 |
|---|---|---|
| side | 256 / 128(モバイル) | 粒子テクスチャの一辺。粒子数は side² |
| sigma / rho / beta | 10 / 28 / 8/3 | ローレンツ系の係数 |
| h / sub | 0.0035 / 3 | RK4 の刻みと 1 フレームの反復回数 |
| spread | 0.08 | 撒き直し時の初期値のばらつき |
| scale / center | 1/21 / (0,0,25) | 表示の縮尺と中心 |
| cam / focal | 3.6 / 2.2 | カメラ距離と焦点距離 |
| spin | 0.08 | 自動回転(rad/s) |
| size / alpha | 1.4(モバイル 1.3)/ 0.14 | 粒子径(px、dpr 倍)と1粒の明るさ |
| decay / fade | 0.004 / 0.86 | 軌跡の減衰(引き算、乗算) |
| hot | [30, 150] | 速さ→橙の範囲 |
| dprMax | 1.75 / 1.5(モバイル) | 表示解像度の上限 |

粒子を 100 万以上にする場合は `sub` を 2 に下げ、`alpha` を粒子数に反比例させる。
