# 反応する格子 — Style Reference
> 方眼紙の上で、カーソルのまわりの格子がレンズのように膨らみ、押された線だけ群青になる。見出しも群青の細い明朝。

**Theme:** light  **Series:** PARTS 055  **World:** 構造計算の結果を図面の上で確かめる道具。力のかかる場所が見える。

## Concept
ヒーロー背景の1パーツ。主役は Canvas2D で描く格子で、格子点がカーソルからの距離に応じて放射状に変位し、ばねで元に戻る。
変位は単調なレンズ写像(並び順が保たれる)なので、中心に点が溜まらず、格子がそのまま膨らんで見える。押された区間だけ群青で重ね描きし、点を打つ。無操作が 2 秒続くと、カーソルは 8 の字を描いて自動で動く(静止画でも主役が伝わる)。

## Signature Technique
Canvas2D。外部ライブラリなし。

- 格子: 間隔 GAP(desktop 44px / mobile 34px)、画面を覆う cols×rows の点 `{ox, oy, x, y, vx, vy, d}`。
- レンズ写像: 点の元位置とカーソルの距離 d、`k = d/R`(R = RADIUS、desktop 230 / mobile 150)。目標半径 `r' = R·(k + (k^LENS - k)·FORCE)`(LENS .42、FORCE .9)。k=0 で 0、k=1 で R、単調増加。目標位置は `o + (r' - d)·(o - cursor)/d`。
- ばね: `v = (v + (target - x)·STIFF)·DAMP`、STIFF .09、DAMP .84。離れると 0.5 秒ほどで戻る。
- 描画:
  1. 横線・縦線を変位した点でつなぐ(`rgba(23,24,28,.16)`、1px)
  2. 変位している区間(`d > .02`)だけ群青で重ねる(1.2px、alpha .7)
  3. 変位している点に半径 `1.2 + 1.6d` の群青の点
  4. カーソル位置に半径 R·.18 の細い輪
- 自動: `idle > AUTO_IDLE(2s)` で `cursor = (W·(cx + ax sin a), H·(.5 + .26 sin 2a))`、a = .5t。`AX = [cx, ax]` はデスクトップ `[.68, .12]`(見出しにかからない右半分を往復)、モバイル `[.62, .22]`。カーソル追従は lerp .12。初期位置は画面の (cx, 50%)。
- dpr は 2 まで。リサイズで格子を作り直す。

## Color Palette
| Token | HEX | 役割 |
|---|---|---|
| --paper | #FAFAF7 | 地 |
| LINE | rgba(23,24,28,.16) | 格子の線 |
| NEAR | #1A3FD6(90%) | 押された線・カーソルの輪 |
| DOT | #1A3FD6(55%) | 変位している格子点 |
| --violet | #1A3FD6 | 見出し・ロゴ・CTA 地 |
| cta-hover | #1232B0 | CTA hover |
| --ink | #17181C | フォーカスリング |
| lead | #3A3C44 | 本文 |
| --mute | #6E7078 | ラベル・フッター |

## Typography
- 見出し: Shippori Mincho 400、`clamp(36px, 5.6vw, 80px)`、line-height 1.22、letter-spacing .02em、群青、`<br>` で2行固定。
- 本文: Zen Kaku Gothic New 400、`clamp(14px, 1.15vw, 17px)`、line-height 1.9、最大 32em。mobile は `<br class="m">` で読点の後ろで折る。
- ラベル・ボタン(.mono): IBM Plex Mono 400/500、12px(mobile 11px)、letter-spacing .1em、大文字。
- ボタン: 13px、letter-spacing .08em、角丸 2px(図面の道具らしい四角さ)。

## Spacing & Layout
- 1画面 = `100svh`、`grid-template-rows: auto 1fr auto`。本文は左寄せ・垂直中央、最大幅 760px、下余白 6vh。`.hero` は `pointer-events:none`(CTA だけ auto)で canvas がカーソルを受ける。
- 左右余白 `clamp(20px, 5vw, 72px)`、上 28px、下 22px(+safe-area)。
- 格子は画面中央を基準に配置し、左右の端で半端が出ないように余分に 2 列・2 行持つ。
- breakpoint 640px: 見出し `clamp(32px, 9vw, 44px)`、フッター2行積み。

## Motion
- ばねの戻り 0.5 秒、カーソル追従 lerp .12。
- 自動の 8 の字は 12.6 秒で1周。操作すると即止まり、2 秒後に再開。
- requestAnimationFrame 1本。`visibilitychange` と IntersectionObserver で画面外は停止。
- `prefers-reduced-motion`: 自動位置で 120 ステップ進めた静止画を1枚描く。
- WebGL を使わないためフォールバック不要。

## Components
- hero: 全画面。上に社名と分類、中央左に eyebrow / h1 / lead / CTA。
- button(.cta): 高さ44px、角丸 2px、群青地に白の等幅文字。hover で濃くなる。focus-visible は墨色のリング。
- footer(.bot): 等幅、左に操作説明、右に `VALE / PARTS 055 / 反応する格子`。
- section: このパーツには無い。

## Do / Don't
- Do: レンズ写像は単調に。並びが入れ替わると格子が破れて見える。
- Do: 変位した区間だけ色を付ける。全体を青くすると方眼紙に戻らない。
- Do: 無操作時は自動で動かす。
- Don't: 格子を細かくしすぎない(GAP 30 未満は線が潰れる)。
- Don't: 影や光彩を足さない。線と点だけ。
- Don't: 見出しを黒にしない。群青が唯一の色。

## References
- Zed: 近白の方眼に群青1色、軽いセリフの見出し、等幅のラベル、2px 角のボタンという構成を抽象化。方眼そのものを主役の表現にした。
- Campsite: 紙のような暖かい地に近黒の文字、色を絞る考え方を抽象化。黄や緑の機能色は使わない。

## Usage
1. `<canvas id="c">` と `<script>` ブロック全体を切り出す。`#hint` も一緒に。
2. canvas は `position:fixed; inset:0`。上に載せる要素は `position:relative; z-index:1; pointer-events:none`、ボタンやリンクだけ `pointer-events:auto`。
3. パラメータは JS 冒頭の `P`:
   - `GAP` 格子の間隔(px)
   - `RADIUS` 影響半径(px)、`FORCE` 強さ(0〜1)、`LENS` レンズの指数(.3〜.6)
   - `STIFF` `DAMP` ばねの硬さと減衰
   - `LINE` `NEAR` `DOT` の3色
   - `AUTO_IDLE` 自動で動き始めるまでの秒数(0 以下で常に自動、大きな値で自動なし)
4. 自動の軌道は `AX`(横の中心と振れ幅)と `step()` の `cur.tx/ty` の式。見出しを左に置く場合は中心を右へ寄せ、振れ幅を狭める。
5. 斜めの格子にしたいときは `build()` で `ctx.setTransform` に回転を足し、カーソル座標を逆回転して渡す。
