# フラッグ — Style Reference
> 淡い灰の面に、竿から深い青緑の布が1枚。風を受けてはためき、布の文字が波打つ。左に太い見出しが1本。

**Theme:** light  **Series:** PARTS 043  **World:** 半日で帆を上げられるセーリングスクール。

## Concept
画面右半分を占める布。主役は質点とばねの布シミュレーションで、風のノイズを法線方向に受けて波打つ。three.js の法線で陰影が付き、布の文字が折れ曲がる。
背景は無地の淡い灰、色は布の青緑1色。文字は左に太いゴシック1本と短文、CTA は布と同じ色。
「風の向きはフラッグで見る」を、そのまま画面で見せる。

## Signature Technique
three.js 0.170 の `PlaneGeometry` の頂点を、自前の Verlet 布で毎フレーム書き換える。

- 格子: 37×25 頂点(mobile 27×18)、布 2.4×1.6 単位。左端の列を竿に固定(pinned)。
- 拘束(距離ばね): 構造 = 隣接で重み 1.0、せん断 = 対角で .7、曲げ = 2つ隣で .35。反復 5 回、固定点は相手が2倍動く。
- 積分(Verlet): `p' = p + (p - prev)*DAMP + f*dt²`、DAMP .985、dt = 1/120 で最大6サブステップ。
- 風:
  ```js
  gust = noise1(t*.9)*GUST + noise1(t*2.7+5)*GUST*.4;              // GUST 1.8
  strength = WIND + gust + act*CURSOR*(mouse.x*.6+.4);              // WIND 2.6、CURSOR 1.6
  wind = (strength, (noise1(t*.6+9)-.5)*1.2 + act*mouse.y*.9, (noise1(t*1.3+3)-.5)*SIDE*2 + sin(t*2.1)*.3);
  // 頂点ごと: 法線 n(前フレームの形から計算)で受ける
  local = .7 + .6*noise1(i*.35 + t*3 + j*.2);
  f = n * dot(n, wind) * local * 4 + (wind.x*.35, -GRAVITY, wind.z*.3);   // GRAVITY 1.6
  ```
- 法線: 各セルの外積を頂点に足して正規化(シミュレーション用)。描画は `geo.computeVertexNormals()`。
- 生地: canvas 1024×683 に色 #137F75、±5 の織りムラ、Inter 800 の文字、竿側に白い縫い目 22px。`MeshStandardMaterial({ map, side: DoubleSide, roughness: .9 })`。
- 光: HemisphereLight(白 / #b9bcc2、1.0)、DirectionalLight 1.6(-3,4,6)、fill .5(4,-1,3)。
- 竿: CylinderGeometry(.028, .034, 4.6)+ 先端の球 .06、#2A2B2F、metalness .4。
- 初期化: 120 ステップ回してから表示(最初から風を受けた形)。

## Color Palette
| Token | HEX | 役割 |
|---|---|---|
| --canvas | #F4F4F5 | 背景・クリアカラー |
| --ink | #121316 | 見出し・ロゴ |
| lead | #3E4046 | 本文 |
| --steel | #6F7179 | eyebrow・フッター |
| --teal(FABRIC) | #137F75 | 布・CTA |
| teal-hover | #0E6961 | CTA hover |
| MARK | #F4F4F5 | 布の文字・縫い目 |
| pole | #2A2B2F | 竿 |

## Typography
- 見出し: Noto Sans JP 700、`clamp(36px, 4.6vw, 66px)`、line-height 1.2、letter-spacing -.02em、左揃え2行。mobile `clamp(30px, 8.6vw, 44px)`。
- 本文: Noto Sans JP 400、`clamp(14px, 1.15vw, 17px)`、line-height 1.9、最大 26em(mobile 24em)。
- eyebrow / ロゴ / フッター: Inter。eyebrow 500 / 12px / .24em、ロゴ 800 / 12px / .22em、フッター 11px / .08em。
- 布の文字: Inter 800、230px(1024px 幅の canvas に対して)。
- CTA: Noto Sans JP 700 / 13px / letter-spacing .08em。

## Spacing & Layout
- 1画面 = `100svh`、`grid-template-rows: auto 1fr auto`。本文ブロックは左、最大幅 520px、縦中央。
- 左右余白 `clamp(20px, 5vw, 72px)`、上 26px、下 22px(+safe-area)。
- eyebrow → h1 22px、h1 → lead 22px、lead → CTA 32px。
- 布の位置: desktop は group を `x = 1.25*s + .45`(s = clamp(w/1440, .8, 1.15))、mobile(幅 640px 未満)は `(0.12, 1.05)` に scale .6 で上半分、竿は `scale.y .79 / y .075` に縮めて文字に掛けない。文字は mobile で下寄せ。
- カメラ: fov 30、z = 9。z=0 の画面高さは 4.82 単位。

## Motion
- 布は常に動く(風のノイズ)。カーソル有効度は .04 で立ち上がり、右にあるほど強風、上下で向きが変わる。
- 1 rAF、`visibilitychange` と IntersectionObserver で停止。dt は最大 .05、サブステップ 1/120 × 最大 6。
- `prefers-reduced-motion`: 360 ステップ回してから1枚だけ描く。フッター文言を差し替える。
- WebGL 非対応: `.still` に竿と台形の布(clip-path)を CSS で置く。

## Components
- hero: 全画面。上にスクール名と業種、左に eyebrow / h1 / lead / CTA、右に布。
- button(.cta): 高さ46px、pill、青緑地に白文字。hover で濃い青緑になり1px浮く。focus-visible は墨色のリング。
- footer(.bot): 11px、左に操作説明、右に `VALE / PARTS 043 / フラッグ`。

## Do / Don't
- Do: 布は1枚、色は1色。文字を入れるなら1語。
- Do: 実在の国や会社のフラッグに似た図柄にしない。無地か文字だけ。
- Do: 竿側を固定し、自由端だけが暴れるようにする(GRAVITY を 0 にしない)。
- Don't: STIFF を .5 以下にしない。布がゴムのように伸びる。
- Don't: 分割を 60×40 以上にしない。反復が追いつかず布がたるむ。
- Don't: 背景に空や海の写真を置かない。無地の灰が布の陰影を見せる。

## References
- LottieFiles: warm gray(#f4f4f5)の面に青緑1色という配分を抽象化。UI のカードは置かず、色を布と CTA の2か所に絞った。
- Hellotime: 白地に太いサンスの見出しを左に寄せる構成を抽象化。SF Pro の代わりに Noto Sans JP 700 + Inter にした。

## Usage
1. `<canvas id="gl">`、`.still`、`#hint`、`<script type="importmap">` と `<script type="module">` を切り出す。three.js 0.170 の importmap が必要。
2. canvas は `position:fixed; inset:0`。上に載せる DOM は `z-index:1`、触る要素だけ `pointer-events:auto`。
3. パラメータは JS 冒頭の `P`:
   - `DPR` 描画解像度
   - `SEG_X` / `SEG_Y` 布の分割、`FLAG_W` / `FLAG_H` 大きさ
   - `ITER` 拘束の反復(5)、`DAMP` 減衰(.985)、`STIFF` 硬さ(1.0)、`BEND` 曲げ(.35)
   - `GRAVITY`(1.6)、`WIND`(2.6)、`GUST`(1.8)、`SIDE` 奥行きの揺れ(.9)、`CURSOR` カーソルの寄与(1.6)
   - `FABRIC` 布の色、`MARK` 文字の色、`TEXT` 文字(空で無地)
4. 布の位置と大きさは `layout()` の `group.position / scale`。レイアウトに合わせて変える。
5. 画像を布に貼るなら `fabricTexture()` を `TextureLoader` に置き換える(相対パス)。
6. 横長の幕にするなら `FLAG_W` を増やし、固定する列を上端(`pinned[i] = 1` for j=0)に替える。
