# やわらかい塊 — Style Reference
> 麻色の机に、橙色のやわらかい塊が1つ落ちて、床で少し潰れている

**Theme:** light  **Series:** PARTS 046  **World:** 架空のクッション研究所「Fuwa」のトップ。素材の硬さを数値で言う代わりに、押すと凹み離すと戻る塊で見せる。

## Concept
画面に塊が1つ。起動時に上から落ちて床で潰れ、揺れながら丸に戻る。カーソルを近づけると輪郭が凹み、離すと内側の圧力で元の形に戻る。クリックで弾くと転がる。塊はゆっくり呼吸している(目標面積が ±4% で往復)。色は橙1色、地は麻色、文字は床の線の下。焦点は塊1つ。

## Signature Technique
圧力つき軟体(pressure soft body)。輪郭の質点を Verlet で動かし、距離拘束と内圧で形を保つ。2D canvas で描く。

1. **質点**: 輪郭に `n=64` 個。`{x, y, px, py}` と、中心からの元のオフセット `rest[i]`。半径 `R = 短辺 × 0.17`(モバイル 0.3)。目標面積 `A0 = πR²`。
2. **圧力**: 多角形の面積 A を shoelace で求め、`pr = clamp(A0·(1 + breath) / A − 1, −0.6, 6) × pressure(4.0)`。各辺の外向き法線 × 辺の長さ × pr × 0.5 × dt² × 60 を両端の質点に加える。潰れるほど強く押し返す。
3. **積分**(1 フレームに 4 ステップ):
   ```js
   v = (p − prev)·drag(0.995);  床に触れていれば v.x *= friction(0.6)
   p += v + g·dt² + 圧力 + (centroid + rest[i] − p)·shape(0.012)   // 形状記憶は弱く、回転は伴わない
   ```
4. **拘束**(8 反復): 隣との距離 `L1 = 2R·sin(π/n)` を硬さ 0.9 で、2 つ先との距離 `L2 = 2R·sin(2π/n)` を硬さ 0.5、4 つ先との距離 `L4 = 2R·sin(4π/n)` を硬さ 0.35 で保つ(表面の滑らかさ。4 つ先が無いと着地後の輪郭に小さな折れが残る)。床 `y ≤ floorY`、左右は画面端から 8px が壁。カーソル円(半径 44px)の中に入った質点は円の縁へ押し出す。
5. **弾く**: クリック位置から重心への向きに、速度 900px/s × 重み `max(0, 1 − 距離/2.2R)` を全質点へ与える(prev をずらす)。
6. **描画**: 閉じた Catmull-Rom(ベジェ変換)で輪郭を描き、放射状グラデーション(#ff8a55 → #ff692d → #d94f1c、中心は左上寄り)で塗る。クリップして内側に4層を重ねる:
   - 左上の広いハイライト(白 35%→0、半径 0.6R)
   - 接地の陰: 底から高さの 32% まで `rgba(120,28,0,.30)` → 0 の線形グラデーション
   - 縁の透け: 輪郭を `blur(0.07R)` で太さ 0.16R の `rgba(255,170,120,.30)`、続けて左上へ (0.05R, 0.06R) ずらした太さ 0.1R の `rgba(255,128,70,.35)` でなぞる(クリップ内なので内側だけ明るくなる)
   - 鋭い照り: 重心から (−0.36R, 高さ×0.2) に 0.22R×0.13R の楕円、白 75%→18%→0
   床には接地量に応じて濃くなる楕円の影(`blur(10px)`)と、床に触れている質点の幅だけに締まった影(`blur(3px)`、`rgba(70,30,10,.28)`、高さ 3.5px)。
7. 起動時に 300 ステップ(1.25 秒)進め、着地して潰れた瞬間から表示する。IntersectionObserver と visibilitychange で画面外停止。

## Color Palette
| Token | HEX | Role |
|---|---|---|
| --linen | #efecea | 地 |
| --paper | #ffffff | 予備の面(未使用) |
| --stone | #dcd9d6 | 床の線 |
| --graphite | #777573 | 本文とラベルと操作説明 |
| --ink | #22201d | 見出し、ブランド名、クレジット |
| --ember | #ff692d | 塊。グラデーションの明部 #ff8a55、暗部 #d94f1c。読み出しの区切り点にも使う |

## Typography
- ブランド名: Inter 500、15px、letter-spacing −0.01em。
- 日本語見出し: Noto Sans JP 400、`clamp(22px, 2vw, 30px)`、letter-spacing −0.01em、line-height 1.4。
- 本文: Noto Sans JP 300、`clamp(13px, 1.05vw, 15px)`、最大幅 30em。2文目を `inline-block` の span で包み、語の途中(「面積/へ」)で折り返さない。質点数は JS で書き込む。
- ラベル: JetBrains Mono 400、11–12px、letter-spacing 0.06–0.08em。圧力比 `A0/A` を 16 フレームごとに更新。
- canvas 不可時は `.fallback` の CSS 円(橙)を表示。

## Spacing & Layout
- hero `min-height: 100svh`、3行グリッド。canvas は背面全面(`touch-action: none`)。
- 余白: 横 `clamp(20px, 5vw, 72px)`、上 `clamp(20px, 3vw, 40px)`、下 `clamp(18px, 2.6vw, 32px)`。モバイル左右 18px。
- 床は `H − 200px`(モバイル `H − 235px`)。文字はすべて床の線の下。塊は `x = 0.56W`(モバイル 0.5W)に落とす。
- breakpoint 760px: ブランド横の説明を消し、フッターを縦積み。

## Motion
- 落下: 画面上端の外から重力 1800px/s² で落ち、着地で潰れて 1–2 秒で丸に戻る。
- 呼吸: 目標面積が周期 4 秒、振幅 4% で往復。静止時も輪郭がわずかに動く。
- 押す: カーソル半径 44px(モバイル 34px)で凹む。離すと圧力で戻る。クリック(250ms 以内、移動 12px 未満)で弾く。
- `prefers-reduced-motion: reduce`: 床の上に置いた状態で 400 ステップ進め、静止した塊を1枚描く。自走はせず、ポインタのイベントごとに1フレームだけ進む。

## Components
- hero: 背面 canvas + 前面テキスト。テキスト層は `pointer-events: none`。
- header: 左にブランド名、右に `64 points · pressure 1.00`(圧力比は動作中に更新)。
- copy: 見出し1行+本文2文。床の線の下。
- footer tag: `VALE / PARTS 046 / やわらかい塊` と操作説明1行(タッチ端末では文言差し替え)。

## Do / Don't
- Do: 2 つ先の質点とも繋ぐ。無いと輪郭がギザギザになる。
- Do: 圧力の上限を決める(6 倍まで)。無いと潰した瞬間に爆発する。
- Do: 影を接地量で変える。浮いているときと潰れているときの違いが伝わる。
- Do: 底を暗く、縁を内側から明るくする。平らな色面だと切り絵に見え、厚みが出ない。
- Don't: 輪郭に線を引かない。縁取りをすると風船やボタンに見える。
- Don't: 質点を 128 以上にしない。反復が足りずゴムの輪になる。
- Don't: 塊を 2 つ以上置かない。衝突処理が無いので重なる。

## References
- Monarch: 麻色の地に墨色の文字、橙 1 色だけという配色の骨格を借りた。橙をボタンから塊そのものに移した。
- Superpower: 白い面に珊瑚色の光る物体を 1 つ置き、周囲を静かにする考え方を借りた。発光を柔らかいグラデーションと影に置き換えた。

## Usage
1. `<canvas id="c">` を hero の背面に置く。フォントは任意。
2. `<script>` ブロック全体を移植する。`boot()` が質点を作り、300 ステップ進めてから描き始める。
3. 床の高さは `resize()` の `floorY`。塊の大きさは `P.radiusK`。
4. 色は `draw()` 内のグラデーション 3 色とハイライトを差し替える。
5. 硬さは `P.pressure`(戻る力)と `P.spring`(表面の張り)で決める。ゼリーなら pressure 1.2 / spring 0.6、ゴムボールなら 4 / 1。

| パラメータ | 既定 | 意味 |
|---|---|---|
| n | 64 | 輪郭の質点数 |
| radiusK | 0.17 / 0.3(モバイル) | 半径(短辺に対する比) |
| gravity | 1800 | 重力(px/s²) |
| drag | 0.995 | 空気抵抗(毎ステップ) |
| pressure | 4.0 | 圧力係数 |
| spring / smooth / smooth3 | 0.9 / 0.5 / 0.35 | 隣・2 つ先・4 つ先のばねの硬さ |
| shape | 0.012 | 元の形への弱い引き |
| friction | 0.6 | 床の摩擦 |
| cursorR | 44 / 34(モバイル) | カーソルの押し込み半径(px) |
| kick | 900 | クリックで与える速度(px/s) |
| breath | 0.04 | 呼吸の振幅(周期 4 秒) |
| iters | 8 | 拘束の反復回数 |

塊を引きずりたい場合は、`pointerdown` で最寄りの質点をつかみ、ロープ(PARTS 045)と同じ方法で追従させる。
