feat(panel): cascading columns, WB colour swatches, stronger HDF glow

Layout
- the panel is a cascade of columns: the rail's tabs, the tab's chips, the
  open chip's sub-chips, then the ruler. A child column no longer hides the
  column it came from (TEMP -> COLOR TEMP keeps TEMP visible); chips stack one
  per row instead of wrapping
- FRAME's WATERMARK opens its own column, so the frame chips stay put
- CREATE RECIPES gets the wide column its two-up form needs

WB colour swatches
- the ruler draws a colour box under the slider that follows the value:
  COLOR TEMP is the Kelvin colour (Tanner Helland), TINT runs green -10 ->
  neutral 0 -> magenta +10

HDF EFFECT
- knee 0.55..0.85 -> 0.45..0.75, blur 0.004+0.015n -> 0.006+0.024n of the
  width, screen alpha 0.15+0.35n -> 0.28+0.52n: a wide halo on the highlights
  instead of a hairline glow. Web copy of toneShader only — the phone keeps
  its own tuning.

Tabs
- rail order is PRESETS, FAVORITED, WB, LIGHT, FX, FRAME, CREATE RECIPES
This commit is contained in:
2026-09-18 06:42:38 +07:00
parent ffdefd2c9c
commit f13fc37b5a
7 changed files with 198 additions and 77 deletions
+14
View File
@@ -27,6 +27,9 @@ export interface SliderDef {
display: string;
// amber value readout once the knob leaves its default (phone's ruler row)
edited: boolean;
// CSS colour the knob is currently driving (WB's temperature/tint), drawn as a
// swatch under the ruler so the hue moves with the number. Absent = no swatch.
swatch?: string;
onChange: (value: number) => void;
// "<" — closes the ruler and reopens the strip it was launched from.
onBack: () => void;
@@ -90,6 +93,17 @@ export function SliderRow({ slider }: { slider: SliderDef }) {
value={slider.value}
onChange={(e) => slider.onChange(Number(e.target.value))}
/>
{slider.swatch ? (
<div
className="swatch"
data-key={`swatch-${slider.key}`}
data-color={slider.swatch}
style={{ background: slider.swatch }}
title={slider.swatch}
>
<span>{slider.swatch}</span>
</div>
) : null}
</div>
</div>
);