Purpose
Provide a visual focus mechanism for vertically-scrolling lists. Rows near the focal center (typically canvas vertical center) appear in full opacity and bold weight; rows further away fade to a lighter, thinner state.
This is the "typographic dimmer" mechanic that gives SP-D editorial-magazine its hypnotic feel.
Params
{
"focal_y_px": 960, // typically canvas_h / 2
"distance_for_full_opacity_px": 0, // rows AT focal are 100%
"distance_for_50_opacity_px": 96,
"distance_for_min_opacity_px": 240,
"min_opacity": 0.18,
"weight_active": 600, "weight_inactive": 400, "weight_transition_distance_px": 96,
"easing": "linear" }
## Behaviour
For each row, compute `d = abs(row.y_in_viewport - focal_y_px)`.
- `opacity = lerp(1.0, min_opacity, clamp(d / distance_for_min_opacity_px, 0, 1))`
- `font_weight = lerp(weight_active, weight_inactive, clamp(d / weight_transition_distance_px, 0, 1))`
Apply both ramps simultaneously. The combination of opacity + weight is what gives the dimmer its sophistication — position alone wouldn't be enough.
## Style pack overrides
- **SP-D (editorial-magazine)** — default partner of `scrolling-index-dual-rail`.
## Quality Checks
- Active row is solid ink color at full weight.
- Inactive rows ramp down smoothly (no stepping).
- Min opacity ≥ 0.15 (less and rows disappear entirely).
- Weight transition synchronizes with opacity transition.
## Failure Modes
- **Rows step rather than ramp.** Easing isn't linear or weight values are integers without smooth interpolation. Use floating-point weight interpolation.
- **All rows look the same.** Distance thresholds too large. Reduce so the active row stands out.
- **Active row stays dim.** Focal_y_px wrong. Verify it's canvas vertical center, not viewport vertical center.