# ホログラム箔 — Style Reference
> 墨色の面に、箔押しした太い見出しが1本。カーソルを動かすと銀の上を虹が走る。

**Theme:** dark  **Series:** PARTS 022  **World:** ホログラムの証明ラベルを1枚から作る印刷会社。

## Concept
見出しの文字をホログラム箔で押した見え方。主役は薄膜干渉の計算で、光源(カーソル)と面の角度から反射色を波長ごとに求める。
箔の粒はノイズで法線を乱して作り、きらめきだけに使う。色の帯は滑らかな厚みムラから出す。
画面は黒に近い紺の無地。色があるのは箔の文字だけで、他は白とグレーの文字。「角度で色が変わる = 複製できない」をそのまま見せる。

## Signature Technique
WebGL1 フラグメントシェーダー。canvas は見出しの箱の大きさだけ(全画面ではない)。外部ライブラリなし。

- マスク: `h1` の computed style(font-family / weight / size / letter-spacing)で 2D canvas に文字を白で描き、アルファをテクスチャにする。DPR 2(mobile 1.5)。
- 法線2種:
  - 滑らか `nS = normalize((gx*EMBOSS, gy*EMBOSS, 1))`。gx, gy はマスクの勾配(2px 差分)。縁の押し跡だけを持つ。
  - 粒入り `nG = normalize(nS.xy + (noise(fc/GRAIN_PX) - .5)*GRAIN, 1)`。GRAIN_PX には DPR を掛けて渡す。
- 光源: カーソル位置 `uLight`(canvas 座標、x は 0..aspect)、`L = normalize((uLight - p, LIGHT_Z))`、視線 `V = (0,0,1)`、`H = normalize(L+V)`。
- 薄膜干渉(干渉色は滑らかな法線で計算):
  ```glsl
  vec3 film(float d, float cosT){            // d: 厚み(nm)
    float ph = 4.*PI*1.45*d*cosT;            // 位相 = 4π n d cosθ
    vec3 lam = vec3(650., 540., 450.);       // RGB を代表する3波長
    vec3 r = .5 + .5*cos(ph/lam);
    return pow(r, vec3(1.6));
  }
  float sw = fbm(p*SWIRL + t*(.03,-.02));
  // 斜めの厚み勾配 BAND(260nm/文字高)を足すと、光の位置を起点に細い色帯が文字を横切る
  float d  = FILM*(1. + FILM_VAR*(sw-.5)) + BAND*(dot(p-light, vec2(.82,.57)) + t*.02); // FILM 520nm、FILM_VAR .7
  vec3 irid = film(d, dot(nS,H));
  ```
- 合成:
  - 銀 `silver = BASE*(.42 + .58*dot(nG,L))`
  - 虹の重み `w = SAT*(.45 + .55*smoothstep(0,.5, 1-cosS))`(斜めほど色が濃い)
  - `col = silver * mix(1, irid*2.1, w)`
  - 照り `pow(cosS,8)*.35` に虹を 6 割乗せる。きらめき `pow(cosG,64)*GLOSS*(.7+.3*hash(floor(fc/GRAIN_PX)))` に虹を半分だけ乗せる。
- 出力はプリマルチプライ `vec4(col*a, a)`、blend `ONE, ONE_MINUS_SRC_ALPHA`。背景は CSS。
- 待機時は光源が楕円軌道をゆっくり回る(IDLE .25)。カーソルが入ると追従(FOLLOW .08)。

## Color Palette
| Token | HEX | 役割 |
|---|---|---|
| --void | #0B0F14 | 背景 |
| --panel | #121820 | CSS 変数(予備)。背景中央の明るみは radial-gradient に直書きの #121921 |
| --bone | #F2F4F6 | ロゴ・ボタン地 |
| lead | #B8C0C8 | 本文 |
| --ash | #8B949E | eyebrow・フッター |
| --line | #1F2831 | 罫(未使用、移植用) |
| BASE | #CCD6E0 | 箔の銀(シェーダー uBase) |
| cta-text | #0B0F14 | ボタン文字 |

## Typography
- 単一ファミリー: Noto Sans JP。
- 見出し(箔): 900、`clamp(64px, 14.6vw, 212px)`、line-height 1.1、letter-spacing .02em。mobile `clamp(56px, 17.5vw, 72px)`。太いほど箔の面積が増えて色が見える。
- 本文: 400、`clamp(14px, 1.15vw, 17px)`、line-height 1.9、最大 30em(mobile 24em)。
- eyebrow: 12px、letter-spacing .26em(mobile .18em)、英字大文字。ロゴ: weight 500 / 12px / .24em。
- ボタン: weight 500 / 13px / letter-spacing .1em。

## Spacing & Layout
- 1画面 = `100svh`、`grid-template-rows: auto 1fr auto`。本文ブロックは中央、最大幅 1100px。
- 左右余白 `clamp(20px, 5vw, 72px)`、上 26px、下 22px(+safe-area)。
- eyebrow → 見出し 30px、見出し → 本文 30px、本文 → CTA 36px。mobile は 22px。
- 見出し canvas の幅 = 文字幅 + 0.12em、高さ = line-height × 行数。ただし hero の内側幅を超えない。
- breakpoint 640px: 見出し `clamp(56px,17.5vw,72px)`、本文に `<br class="m">` の改行を足して3行、フッター2行積み。
- 末尾の句点の空きで字面が左に寄るため、641px以上では h1 を `translateX(.28em)` して字面の中心を画面中央に合わせる。

## Motion
- 光源 lerp 0.08、待機周回 `(cos(t*.25)*.6*aspect, sin(t*.175)*.9)`。カーソル有効度は 0.05 で立ち上がる。
- 厚みムラの渦が `t*.03` で流れ、何もしなくても色がゆっくり変わる。
- requestAnimationFrame 1本、dt は 0〜0.05 秒。`visibilitychange` と IntersectionObserver で停止。
- `prefers-reduced-motion`: 光源を `(0.72·aspect, 0.85)`(右上)に固定して1フレーム描く。フォント読込後とリサイズ時に描き直す。フッター文言を差し替える。
- WebGL 非対応: `h1.css` に切り替え、CSS の linear-gradient を `background-clip:text` で文字に入れる。

## Components
- hero: 全画面。上に社名と業種、中央に eyebrow / 箔の h1 / lead / CTA。
- h1.foil: `data-text` に文字、中に `.sr` の同文と `<canvas>`。改行は `\n`。
- button(.cta): 高さ44px、pill、白地に紺の文字。hover で純白になり1px浮く。focus-visible は白のリング。
- footer(.bot): 11px、左に操作説明、右に `VALE / PARTS 022 / ホログラム箔`。

## Do / Don't
- Do: 箔は1か所。見出しだけに使い、ボタンやロゴには使わない。
- Do: 背景は無地の暗色。虹を目立たせるのは黒の余白。
- Do: GRAIN は 0.04〜0.1(既定 .06)。0.15 以上で砂目になる。粒はきらめきにだけ効かせ、干渉色には混ぜない。
- Don't: 干渉色の計算に粒入りの法線を使わない。砂目の confetti になる。
- Don't: FILM_VAR を 1 以上にしない。帯が細かくなりすぎて箔に見えない。
- Don't: 背景に紫グラデや光の玉を置かない。箔の色が負ける。

## References
- Turso: 深い紺黒の無地に白い文字、色は1か所の「点灯」だけという配分を抽象化。ミントの accent は使わず、点灯の役を箔の虹に替えた。
- Mercury: 文字の重みで画面を支え、ボタンは pill 1つという構成を抽象化。コバルトは使わず、ボタンは白にして色を箔に集めた。

## Usage
1. `<h1 class="foil" data-text="...">` ブロック(中の `.sr` と `<canvas>`)と `<script>` を切り出す。CSS の `h1.foil` / `h1.foil.css` も一緒に。
2. 見出しの書体・サイズは CSS の `h1.foil` で指定する。JS は computed style を読んでマスクを描くため、CSS を変えれば箔も追従する。複数行は `data-text="一行目\n二行目"`。
3. canvas の alpha は premultiplied。背景は CSS で自由に変えられる(暗い地のほうが色が出る)。
4. パラメータは JS 冒頭の `P`:
   - `DPR` 描画解像度(desktop 2 / mobile 1.5)
   - `FILM` 厚み nm(520)、`FILM_VAR` ムラ(.7)、`SWIRL` ムラの周波数(.9)
   - `BAND` 斜めの厚み勾配(260nm/文字高)。光から遠い字は銀、近い字ほど虹の帯が走る
   - `GRAIN` 粒の強さ(.06)、`GRAIN_PX` 粒の大きさ(.55px)
   - `SAT` 虹の濃さ(.66、0で銀箔)、`GLOSS` きらめき(.7)、`EMBOSS` 縁の押し跡(1.4)
   - `LIGHT_Z` 光源の高さ(.32、小さいほど色の変化が急)
   - `FOLLOW` 追従(.08)、`IDLE` 待機の回転速度(.25)
   - `BASE` 銀の色
5. 金箔にするなら `BASE` を `[0.95,0.78,0.42]`、`SAT` を 0.15 に下げる。
6. 複数の箔要素を置く場合は要素ごとに canvas と program を作る。1つの rAF から順に draw する。


