# 奥行きのある写真 — Style Reference
> a misty ridge photograph on warm paper that moves like a window: near pines slide, far ridges barely drift, and a draggable split shows the depth map the parallax is built from.

**Theme:** light  **Series:** PARTS 098  **World:** 山小屋の宿泊案内。一枚の風景写真に手続きで奥行きをつけ、カーソルで視差が動く。

## Concept
A single flat photograph given depth without a depth file. Misty mountain photographs already encode distance: atmospheric haze makes every farther ridge paler, and higher in the frame is usually farther away. The shader combines those two cues into a depth value per pixel and displaces near pixels more than far ones as the pointer moves. A slow automatic drift keeps the parallax alive at about half amplitude, and a vertical split handle, set to the middle on load, shows the photo on the left and the derived depth map on the right so the mechanism is visible in a still frame. The copy, in a mincho face on warm paper, stays out of the frame.

## Signature Technique
Raw WebGL1, one fullscreen triangle inside a 16:9 frame.

- **Procedural depth.** `depthAt(uv)`: `haze = smoothstep(0.08, 0.95, luminance)`, `height = 1 - uv.y`, `depth = mix(height, haze, hazeWeight)` with `hazeWeight` 0.65. 0 is near, 1 is far. For this photo the dark pines read as 0.1, the far pale ridges as 0.8 to 0.95, the sky as 1.
- **Layered parallax search.** For the output pixel, test `layers` candidate depths d from near to far (16 desktop, 10 mobile). Each candidate looks up `q = uv + offset * (1 - d)`, the place a pixel at that depth would have come from, and reads `depthAt(q)`. The candidate whose stored depth is closest to its own d wins; its colour is drawn. This is a cheap inverse mapping that gives correct occlusion order (near layers cover far ones) with no geometry.
- **Offset.** `offset = (-ptr.x * parallax + kb * 0.3, ptr.y * parallax * 0.6 + kb * 0.15)`, `parallax` 0.045 of width. `kb` is a slow Ken Burns drift (`kenburns` 0.05 over 24 s) that also adds up to 2 percent zoom; a base zoom of 1.12 hides the edges.
- **Drive.** Auto target is a figure-eight: `ax = sin(2 pi t / 12 + pi / 6)`, `ay = 0.35 sin(4 pi t / 12)`. When the pointer is over the frame it blends 70 / 30 with the pointer. Both lerp with `1 - exp(-5 dt)`.
- **Split.** `uSplit` in 0..1; fragments with `v.x > uSplit` draw the depth visualisation (deep green to paper white) instead of the photo. The handle is `role="slider"` with pointer capture and arrow-key steps of 5 percent; its line and the right caption use `mix-blend-mode: difference` so they read on both halves.
- **Texture.** The photo (896 px, about 12 KB WebP) is embedded as base64 so WebGL can upload it from `file://`; clamp to edge, linear, no mipmaps.
- **Reduced motion.** Auto drift frozen at a fixed offset, Ken Burns off; the pointer and the split still work.

## Color Palette
| Token | HEX | Role |
|---|---|---|
| --paper | #f6f3ec | page, split line, far end of the depth ramp |
| --ink | #1d2a24 | heading, pill, caption |
| --mute | #6f7a74 | eyebrow, body, tag |
| --hair | rgba(29,42,36,.16) | frame border |
| (frame bg) | #CFD6D9 | frame fill shown before the photo texture loads |
| --moss | #2f6b4f | focus ring on the handle |
| depth near | rgb(31,51,41) | near end of the depth visualisation |

## Typography
- **Shippori Mincho** 400 for the h1 only: clamp(36px, 3.8vw, 56px), letter-spacing 0.04em, line-height 1.3. A mincho headline against a sans body marks the page as hospitality, not tech.
- **Noto Sans JP** 300 / 400 / 500 for the body (clamp(14px, 1.05vw, 16px), max 34ch) and the pill.
- **IBM Plex Mono** 400 for the eyebrow, captions and tag.

## Spacing & Layout
- Grid 4 / 8, copy left (max 380px), frame right, gap `clamp(24px, 4vw, 64px)`, centred in `100svh`.
- Frame `aspect-ratio: 16 / 9`, hairline border, captions 16px in from the corners, handle full height and 28px wide with a 2px line and an 18px ring at the middle.
- Under 760px: frame first, copy second, tag bottom left.

## Motion
- Figure-eight drift period 12 s; Ken Burns period 24 s; pointer response about 0.2 s.
- Split handle: direct, no easing.
- Pill: no transition.

## Components
- **frame**: canvas, left caption `Parallax NN%`, right caption `Depth map`, split handle.
- **copy**: eyebrow, mincho h1, one sentence, outlined pill.
- **tag**: `VALE / PARTS 098 / 奥行きのある写真` plus hint.
- **fallback**: without WebGL a note appears under the copy; the frame shows a flat grey.

## Do / Don't
Do
- Use photographs with haze or fog; the haze is the depth sensor.
- Keep parallax under about 5 percent of width; beyond that the layer search shows seams.
- Show the depth map somewhere; it turns a trick into an explanation.

Don't
- No blur on far layers unless the photo is already soft there; blurring doubles the haze cue and flattens it.
- No parallax on portraits or interiors with this depth model; luminance does not mean distance there.
- No colour UI inside the frame beyond the single split line.

## Usage
1. Put `<div class="frame"><canvas id="gl"></canvas><div class="handle" id="handle"></div></div>` with the photo's aspect ratio.
2. Copy the `<script>` block; replace the base64 in `#img` (or use a same-origin URL over http).
3. For a photo without haze, replace `depthAt` with a sampled depth texture (`texture2D(tDepth, uv).r`) and keep the layer search as is.
4. To drop the split, remove the handle and set `uSplit` to 1.0.
5. Tune `P`.

| パラメータ | 既定 | 意味 |
|---|---|---|
| parallax | 0.045 | 最前景のUVずれ(幅に対する割合) |
| zoom | 1.12 | 端が見えないための基本ズーム |
| kenburns | 0.05 | ゆっくりした漂いの振幅 |
| period | 12 | 自動ドリフト1周の秒数 |
| pointerWeight | 0.7 | カーソルと自動の混合比 |
| hazeWeight | 0.65 | 深度を明るさから取る割合(残りは画面上の高さ) |
| layers | 16 / 10(モバイル) | 深度スライスの数。多いほど境界が滑らか |

## References
- **Tuple** (stock/refero/md/tuple.md): clean white surfaces with one accent and a dark band that lets the light sections breathe. Abstracted: a quiet light page where the single rich object is the dark photo. Changed: no violet; the accent is a moss focus ring and the photo's own greens.
- **Craft** (stock/refero/md/craft.md): botanical conservatory on warm parchment, vivid green specimens, one quiet forest room. Abstracted: warm parchment paper and deep green ink. Changed: the specimen is a moving landscape, the type is mincho rather than a grotesque.
