# 百年の棘 — Style Reference
> 古紙の上で、深緑の茨がスクロールに合わせて城を覆い、百年目に花になる

**Theme:** light  **Series:** FABLE 004  **World:** 眠れる森の美女(ペロー/グリム)。茨に覆われた城、針が落ちてから百年。

## Concept
スクロール位置が時間。heroは420vhのスクロール区間を持つsticky画面で、0年から100年までのカウンタと、L-systemで生成した茨の伸びが同じ進捗値 `g` で動く。開いた瞬間、最初の40年はひとりでに過ぎる(0.4s 待って 3s の ease-out で g を 0→0.4)。城の足もとに根を置いた茨だけが先に壁を這い上がり(手前の茨はスクロール分だけ伸び、見出しを隠さない)、静止画でも「茨が城を覆っていく途中」が見える。下へ進むほど茨が画面を覆い、100年で城が見えなくなる。その下に「規則」「眠り」「百年目」の3区画。最後の区画で同じ茨の先端に花が開き、花びらが落ち、霧が薄れて城が戻る。色は古紙と深緑の2色で進め、花の桃色は最後の区画だけで使う。

## Signature Technique
L-system(文字列書き換え)で茨を生成し、SVG pathのstroke-dashoffsetで伸びを制御する。

- axiom `F`、rule `F → FF+[+F−F−F]−[−F+F+F]`(確率0.5で鏡像の `FF−[−F+F+F]+[+F−F−F]`)、depth 3、Fの本数 512
- 角度 22.5°(各回転に0.7〜1.3倍の揺らぎ)、各Fで ±0.11rad の向きの揺れ、枝の深さごとに長さ 0.82倍・線幅 0.78倍
- 城の蔓: L-system とは別に、城の写真のシルエット上端を画像座標で 8px おきに採った表(x 432〜648、上端 y 528〜622)を持ち、`object-fit: cover` と `object-position` から画面座標へ写す。蔓は城の裾(y 646)から 3px 刻みで上端まで登り(振れ幅 1.2〜3px の sin)、上端に着いたら胸壁の輪郭に沿って 10〜36px 横へ這い、端で少し垂れる。棘は 6px ごとに左右交互の三角。SVG は城の要素の中に置き、城と同じ視差と拡大で動く。伸びは `min(1, g/0.42)`、蔓ごとに start 0〜0.35。城の形が蔓越しに読める。
- 先細り: 深さ0〜1の枝は3セグメントごとに別 `<path>` に分け、線幅 `base × 0.78^depth × (1 − 0.55 × d/maxD)`(base: hero desktop 4.8 / mobile 3.6、最小0.7)。根元が太く先が細くなる
- 亀(turtle)は `[` `]` の間を1本のpolylineとして記録し、各polylineを `<path>` にする。pathごとに根からの距離 `d0` と長さ `len` を持ち、`stroke-dasharray = len`、`stroke-dashoffset = len − clamp(G − d0, 0, len)` とする。`G = g × maxD × 1.02`。これで根から先端へ一定速度で伸びる
- 棘は各Fの中点に法線方向(左右交互)の塗りの鉤形(`M b1 Q c1 tip Q c2 b2 Z`、長さ H×0.017、根元幅 0.26×長さ)を置き、根からの距離で18個のバケットに分け、バケットごとに1つの `<path>` にまとめ opacity で出す(要素数を抑えるため)
- hero desktop: 城の蔓15本(mobile 11本)+ 近景11株(うち2株は城の真上に根を置き、100年で城を隠す)+ 遠景2株、mobile: 近景6株 + 遠景1株。株ごとに `start`(0〜0.52)をずらし `(g − start)/(1 − start)` で伸ばす
- 乱数は mulberry32 で seed 固定。リサイズで幅が変わった時だけ再生成
- パララックス: 城画像 `translateY(−g×2.5vh)`、遠景茨 `−5vh`、近景茨 `−9vh`。霧(古紙色の面)の不透明度 `0.1 + 0.7g`
- フィルムグレイン: 画面固定の WebGL canvas(fragmentで hash ノイズ2層 + ビネット)を `mix-blend-mode: multiply` で重ねる。24fps、mobileは0.6倍解像度。WebGL不可なら canvas を外すだけで内容は成立する
- 花: Canvas2D。茨の深さ2以上の先端から株ごとに34点(mobile 22点)を選び、区画の進捗 `q` と各点の開始値 `s` で `k = clamp((q − s)/0.22)` を取り、back-easeで5枚の楕円花弁を開く。花びら粒子は開いた花から 240ms に1枚(mobile 420ms)生まれ、重力・横揺れ(sin)・回転で落ちる。上限110枚(mobile 40枚)

## Color Palette
| Token | HEX | Role |
|---|---|---|
| --paper | #DFE1D3 | 地色。緑灰に寄せた古紙 |
| --paper-2 | #D2D6C5 | 規則パネルの面 |
| --ink | #1B3328 | 本文・見出し・ボタン |
| --green | #2E5A44 | ラベル、罫線、百年目区画の茨 |
| --thorn | #1C4231 | 茨の近景(hero・規則・眠り)。紙とのコントラストを最優先 |
| --moss | #7A9177 | CSS トークン。眠り区画の中景茨は #93A28F |
| --mist | #BFC6B8 | CSS トークン。遠景茨は hero #7F9080(不透明度 .85)、眠り区画 #C3CABD |
| --blush | #D9A1AA | 花弁。最終区画のみ |
| --rose | #B35A70 | 花芯、フォーカスリング |
| --line | rgba(27,51,40,.16) | 罫線・パネル枠 |

## Typography
- 見出し・本文: Shippori Mincho 400/500(Google Fonts)。`font-feature-settings: "palt"`
- ラベル・数字: IBM Plex Mono 400/500。tracking 0.2em、小文字サイズ11〜12.5px
- h1 `clamp(54px, 9vw, 124px)` / line-height 1.08 / tracking 0.06em / weight 500
- h2 `clamp(28px, 3.4vw, 44px)`(2カラム内は `clamp(26px, 2.4vw, 34px)`)/ line-height 1.2 / tracking 0.06em
- lead `clamp(16px, 1.3vw, 19px)` / line-height 1.9 / tracking 0.04em / max-width 31em
- 年数 `clamp(36px, 4vw, 56px)` mono 500 tabular-nums
- 見出しの改行は `<br>` で固定し、句読点の後で折る

## Spacing & Layout
- 基本単位 8px。区画の縦余白 `clamp(96px, 16vh, 180px)`、締めは `clamp(120px, 22vh, 240px)`
- 横 gutter `clamp(20px, 4vw, 56px)`、最大幅 1200px
- 規則区画: grid 5fr / 7fr、gap `clamp(32px, 6vw, 96px)`、860px以下で1カラム
- sticky区画の高さ: hero 420vh、眠り 190vh、百年目 260vh。stageは `100svh`
- breakpoints: 860px(grid)、640px(文字サイズ、hint非表示、城画像の object-position 36%)

## Motion
- 全てスクロール進捗に従属。自走する動きはグレイン(24fps)、規則パネルの初回成長(2.8s, cubic-out)、落ちる花びらの3つだけ
- 進捗: `p = −rect.top / (wrapH − stageH)`。hero の茨 `g = max(clamp((p − 0.04)/0.88), intro)`(intro は読み込み直後に 0→0.4 へ自動で進む)。霧はスクロール分の g だけで濃くなる。title は `p 0.03→0.16` で消え、終わりの一文は `p 0.9→1.0` で出る
- 眠り区画のパララックス: 3層を `(q − 0.5) × H × (−0.08 / −0.2 / −0.42)` で移動。上下は mask-image で溶かす
- rAFは1本。各区画は画面外なら更新を飛ばす。`visibilitychange` で停止・再開
- reduced-motion: パララックス・グレインの更新・花びらの落下を止める。茨の伸びはスクロール連動のため残る。規則パネルは即座に全体表示。`scroll-behavior` も auto

## Components
- hero: sticky stage。層の順: 城画像(radial mask + 縁の古紙グラデ) → 霧 → 遠景茨SVG → 近景茨SVG → 見出し → 終わりの一文 → 年数カウンタ(左下) → ヒント(右下、mobile非表示)
- section(規則): 左に見出し+本文+mono表(axiom / rule / angle / depth)、右に4:3のパネル(radius 24px、1px枠)。パネル内に1株の茨が伸び、右下のpillボタンで別seedに生え変わる
- section(眠り): sticky stage に3層の茨。中央テキストは古紙色のradialで背を抜く
- section(百年目): 城画像(霧が晴れる)+ 静止した茨SVG(opacityが1→0.5)+ 花のcanvas。見出しは左上に古紙色の背
- button: pill、1px ink 枠、hoverで ink 塗り。solid版は ink 塗り・hoverで green。focus-visible は rose 2px outline
- footer: 1px 罫の上に mono 11px `VALE / FABLE 004` と作品名

## Do / Don't
Do
- 色は古紙と深緑で進め、桃色は最後の区画だけに置く
- 茨の数を増やすより、株の開始時刻 `start` をずらして時間差で覆う
- テキストの背に古紙色のradialを敷いてから茨の上に置く
- 伸びはdashoffsetで、出現はバケット単位のopacityで(個別要素のopacity更新は避ける)
- seedは固定し、何度開いても同じ茨にする

Don't
- 茨を塗り(fill)にしない。線幅の違いだけで奥行きを出す
- 画像の上に直接文字を置かない(霧と古紙のmaskを挟む)
- 1画面に見出しと本文以外の文章を足さない
- 花びらを全画面に降らせない。開いた花からだけ落とす
- グレインを強くしない(±6%まで)

## References
- Ready(violet daylight workspace): 「1色だけが仕事をする」考え方と、小さいラベルに広いトラッキングを使う型。ここでは色を桃色1つに絞り、しかも最終区画でしか使わない形に変えた。書体は幾何サンセリフを捨て、明朝+モノに置き換えた
- Campsite(warm paper workspace): 紙のような地色と、製品(ここでは茨のシミュレーション)を大きく全幅で主役にし、文章を小さく抑える構成。地色はクリームを避けて緑灰の古紙(#DFE1D3)にし、Inter一本の階層をサイズ差で作る方針を Shippori Mincho のサイズ差に置き換えた
