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
+63 -15
View File
@@ -62,27 +62,41 @@
.rail button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }
.rail button:hover { color: var(--text); }
/* --- chip column -------------------------------------------------------- */
/* --- panel columns ------------------------------------------------------- */
/* The panel is a cascade: the rail holds the tabs, then one column per open
level — the tab's chips, the open chip's sub-chips, the open ruler. A child
column never hides the column it came from, so the path reads left to right. */
.chips {
width: var(--chip-w);
flex: 0 0 auto;
max-width: 62vw;
display: flex;
flex-direction: row;
align-items: stretch;
border-right: 1px solid var(--border-soft);
background: var(--bg);
overflow-y: auto;
padding: 10px;
overflow-x: auto;
overflow-y: hidden;
}
.col {
width: var(--col-w);
flex: 0 0 auto;
display: flex;
flex-direction: column;
gap: 8px;
padding: 10px;
overflow-y: auto;
border-right: 1px solid var(--border-soft);
}
.chips h2 { margin: 0 0 2px; font-size: 11px; letter-spacing: 0.14em; color: var(--text-dim); font-weight: 600; }
.col:last-child { border-right: none; }
.col-slider { width: var(--slider-w); }
/* CREATE RECIPES draws a two-up form, so its column is the wide one. */
.col-create { width: 300px; }
.col-sub { background: var(--bg-elev); }
.chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
/* One strip at a time: the ruler, the open group's options, the recipe list and
the watermark fields each sit on their own row above the main chip row. */
.strip { border-top: 1px solid var(--border-soft); padding-top: 8px; display: flex; flex-direction: column; gap: 8px; }
/* RESET stays pinned at full size; the tab's chips take the rest and scroll. */
.main-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.main-row > .chip-row:last-child { flex: 1 1 auto; min-width: 0; }
.wm-extra { border-top-color: var(--accent-line); }
/* In a column the chips stack: one chip per row, full width. */
.col .chip-row { flex-direction: column; align-items: stretch; }
.col .chip { justify-content: space-between; text-align: left; }
.wm-extra { border-right-color: var(--accent-line); }
.chip {
border: 1px solid var(--border);
background: var(--bg-elev);
@@ -94,6 +108,7 @@
align-items: center;
gap: 6px;
}
.col-sub .chip { background: var(--bg); }
.chip[aria-pressed="true"], .chip.on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
/* Edited value, strip closed: the text glows amber, the border does not. */
.chip.amber, .chip.amber .val { color: var(--accent); }
@@ -101,14 +116,36 @@
.chip .pro { font-size: 9px; letter-spacing: 0.08em; color: var(--accent); }
.chip:disabled { opacity: 0.4; cursor: not-allowed; }
/* The ruler row: "<" back button, label + live value, full-width slider. */
/* The ruler column: "<" back button, label + live value, slider, colour swatch
for the knobs that drive a hue (WB's TEMPERATURE / TINT). */
.slider-row { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 10px; display: flex; align-items: center; gap: 10px; }
.col .slider-row { flex-direction: column; align-items: stretch; gap: 6px; }
.slider-row .ruler { flex: 1 1 auto; min-width: 0; }
.slider-row .head { display: flex; justify-content: space-between; font-size: 11px; letter-spacing: 0.1em; color: var(--text-dim); }
.slider-row .head b { color: var(--text); font-family: var(--mono); letter-spacing: 0; }
.slider-row .head b.amber { color: var(--accent); }
.slider-row .swatch {
height: 26px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
}
.slider-row .swatch span {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.06em;
color: #fff;
mix-blend-mode: difference;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.slider-row .back {
flex: 0 0 auto;
align-self: flex-start;
border: 1px solid var(--border);
background: var(--bg-elev);
color: var(--text-dim);
@@ -299,7 +336,18 @@ input[type="range"] { width: 100%; accent-color: var(--accent); }
padding: 4px;
}
.rail button { flex: 1 0 auto; min-width: 62px; }
.chips { order: 1; width: auto; border-right: none; border-bottom: 1px solid var(--border-soft); max-height: 42vh; }
/* The cascade still runs left to right; the columns themselves scroll rather
than the page, so the stage keeps its width. */
.chips {
order: 1;
width: auto;
max-width: none;
max-height: 42vh;
border-right: none;
border-bottom: 1px solid var(--border-soft);
}
.col { width: 148px; padding: 8px; }
.col-slider { width: 200px; }
.col-create { width: 260px; }
.stage { order: 0; flex: 1 1 auto; }
.chip-row { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }
}