git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commit5f478a61d437ebd6ccb5834394c21494991f1571
parentc86d6f666b
authorLucas Galante <[email protected]>
date2026-09-20 14:31
docs: RFC material step 2 done; CLAUDE.md says where a plate's material now lives

Co-Authored-By: Claude Fable 5.1 <[email protected]>

 CLAUDE.md            | 13 ++++++++++---
 docs/rfc-material.md | 14 +++++++++++++-
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index b026b89..6adf1cf 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -255,9 +255,16 @@ What this buys, and where the code is heading:
   light: the old `relief_shade::Material`). `docs/rfc-material.md` is the design and
   its phase tracker. `Material::fill_tint` is the ONE place the blur-behind sentinel
   (a negative alpha) is written; `PlateSpec::fill` and `param_plate_fill` call it.
-  Rung defaults: `Material::root()` / `pane()` / `control()`; a well floor is
-  `host.floor(lifted)`. Step 1 only — the rungs still carry `color` + `blur` until
-  step 2 threads the type through.
+  Rung defaults: `Material::root()` / `pane()` / `control()`, `popover(base)` for
+  menus; a well floor is `host.floor(lifted)`. `PlateSpec`, `ControlPlate.face`
+  (`Option<Material>`: `None` = the surface below IS the face) and the prims
+  `Plate` / `Bevel` / `Sphere` / `Droplet` carry one, and `PaintCtx::plate` /
+  `bevel` / `sphere` / `droplet` / `inset_plate` take one; the tessellator reads
+  each prim's fill and push-constant finish from it, and only the carves still take
+  the DE finish. `Material::from_fill` / `face` decode a colour a legacy site still
+  holds (the flat-path `RenderTarget` is colour-typed) — a new site says
+  `Material::opaque` / `with_frost` instead. **`tests/plate_golden.rs` is the exit
+  test for any change that must not move a pixel**: dump before, compare after.
 - **One plate spec per rung, not five copies.** The root and pane rungs are
   `scene::paint::PlateSpec` (RFC 7b, painted by `PaintCtx::plate`). The
   control rung is `scene::paint::ControlPlate` (re-exported from `widget`):
diff --git a/docs/rfc-material.md b/docs/rfc-material.md
index 9475e1d..2a7ac90 100644
--- a/docs/rfc-material.md
+++ b/docs/rfc-material.md
@@ -396,7 +396,19 @@ keeps the `Material` alias. `Frost::Frosted` already carries `radius` at
 - *Exit:* `cargo test -p cce-ui scene::`; the `relief_shade` shader-constant test still
   passes; every client builds; prim dump identical.
 
-**Step 2 — thread it through the rungs.**
+**Step 2 — thread it through the rungs.** *DONE 2026-09-20*, as four commits (2a–2d),
+each prim-identical against a tessellation dump taken before 2a (`tests/plate_golden.rs`,
+148518 lines, two scales × both edge paths). Deviations from the text below, each
+deliberate: `DropletSpec` KEEPS `gleam` / `shine` / `rim` as the config spelling and
+`DropletSpec::finish()` derives the `Finish` the material carries — the runner's hand-packed
+slots are gone, which was the point. `PaintCtx::inset_plate` takes `Option<&Material>`
+(`None` = the surface below is the face), as does `ControlPlate.face`. `well_floor` keeps
+today's overlay emission: switching it to `host.floor()` is not prim-identical for a
+translucent or frosted pane (a darkened fill at the pane's alpha composites differently
+from a darkening overlay on the resolved plate), so it moves to step 3, where pixels may
+change. `Material::from_fill` / `face` bridge the colour-typed flat path
+(`layout::RenderTarget`), which is unchanged. `layout::tree_blur` has no reader and was
+left alone. `Material::popover` is the menu recipe the three menu sites had each spelled.
 - `PlateSpec`, `ControlPlate`, `Prim::Plate`, `Prim::Bevel`, `Prim::Sphere`,
   `Prim::Droplet` carry a `Material`; `PaintCtx` signatures per § 4.
 - `DropletSpec` loses `gleam` / `shine` / `rim` to its material's `Finish`; the runner's