status bar
git clone https://git.lucas.co/cce-status-interface.git
feat: text_relief letterpress underlay + droplet core knob
module { text_relief } draws a translucent white copy 0.75px
down-right beneath each module text run (engraved text — a lit edge
that carries the letterforms on dark backdrops and vanishes on light
ones). module { droplet } gains the core key for cce-ui's new
interior-density term.
Co-Authored-By: Claude Fable 5 <[email protected]>
CLAUDE.md | 7 +++++--
src/config.rs | 9 +++++++++
src/main.rs | 15 ++++++++++++++-
3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 7a20b4e..a3a6069 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -140,14 +140,17 @@ background_blur tint scaling still applies on top) and `module { text_color }`
style — cce-ui's `Prim::Droplet`, shader mode 10; the key's PRESENCE enables
it, its value is whitespace-separated `k=v` pairs onto `DropletSpec` — sag,
belly, belly_w, blend, sheet_r, attach, clarity, dome, band, gleam, shine,
-rim, bow, curve; defaults = the oval dewdrop (no belly; attach 0.42 +
+rim, bow, curve, core; defaults = the oval dewdrop (no belly; attach 0.42 +
sheet_r 0.58 fill the height so there is NO straight side; bow arcs the
bottom; curve 2.6 = superellipse joins, so everything but the flat top is one
continuous curve), belly>0 brings back the pendant-pool look —
warn-and-skip on unknown keys; the expanded menu box becomes the drop growing,
and drops inset 1px from the surface bottom for the silhouette's AA feather)
and `module { text_raise }` (lifts module text above vertical center, logical
-px, bar-side only — every module funnels through `centered_text_y`). Everything is read through
+px, bar-side only — every module funnels through `centered_text_y`) and
+`module { text_relief }` (letterpress underlay strength 0-1: a translucent
+white copy 0.75px down-right beneath each non-boxed text run — engraved text,
+guaranteed contrast on dark backdrops). Everything is read through
`cce_ui::config::cached_config()`; KDL is converted to JSON
(`cce_ui::config::parse_kdl_to_json`) and looked up by **explicit JSON
pointer only**: every key names its canonical nesting
diff --git a/src/config.rs b/src/config.rs
index df69ca4..6a12e74 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -205,6 +205,7 @@ pub(crate) fn read_droplet_from_config() -> Option<cce_ui::scene::paint::Droplet
"rim" => spec.rim = v,
"bow" => spec.bow = v,
"curve" => spec.curve = v,
+ "core" => spec.core = v,
_ => log::warn!("module.droplet: unknown key '{}' — skipped", key),
}
}
@@ -218,6 +219,14 @@ pub(crate) fn read_text_raise_from_config() -> f32 {
cfg_f32("/module/text_raise").unwrap_or(0.0)
}
+/// `module { text_relief }` — letterpress underlay strength (0 = off, 1 =
+/// opaque): each module text run gets a white copy offset ~0.75px down-right
+/// BENEATH the glyphs, so dark text keeps a lit edge on dark backdrops (the
+/// engraved-text treatment, matching the DE's relief language). Bar-side only.
+pub(crate) fn read_text_relief_from_config() -> f32 {
+ cfg_f32("/module/text_relief").unwrap_or(0.0).clamp(0.0, 1.0)
+}
+
pub(crate) fn read_status_box_corner_radius_from_config() -> f32 {
// App-native ONLY (~/.config/cce/cce-status-interface/config.kdl,
// merged over the shared config by cce-ui): `module { corner_radius }`.
diff --git a/src/main.rs b/src/main.rs
index 8f2bae3..6db6fd0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -260,6 +260,9 @@ struct StatusApp {
/// first so module content sits on the drop.
droplet_boxes: Vec<(f32, f32, f32, f32, [f32; 4])>,
droplet: Option<cce_ui::scene::paint::DropletSpec>,
+ /// Letterpress underlay strength for module text (0 = off) — see
+ /// `read_text_relief_from_config`.
+ text_relief: f32,
text_prims: Vec<TextPrim>,
scale_factor: f64,
@@ -367,6 +370,7 @@ impl StatusApp {
self.box_bevel_depth = read_status_box_bevel_depth_from_config();
self.droplet = read_droplet_from_config();
self.droplet_boxes.clear();
+ self.text_relief = read_text_relief_from_config();
self.status_bar.set_rect(0.0, 0.0, self.width as f32, self.height as f32);
// The surface itself is transparent: every StatusApp is a single
@@ -1116,6 +1120,7 @@ impl cce_ui::engine::Application for StatusApp {
rounded_boxes: Vec::new(),
droplet_boxes: Vec::new(),
droplet: None,
+ text_relief: 0.0,
text_prims: Vec::new(),
scale_factor: 1.0,
width: if selected_module.is_some() { 120 } else { 1920 },
@@ -1412,7 +1417,15 @@ impl cce_ui::engine::Application for StatusApp {
for (text, tsize, x, y, color, font, bounds, layout) in &self.text_prims {
match layout {
Some(l) => pc.text_boxed(text.clone(), *x, *y, *tsize, *color, font.clone(), *bounds, cce_ui::scene::paint::TextAttrs::default(), *l),
- None => pc.text_with(text.clone(), *x, *y, *tsize, *color, font.clone(), *bounds),
+ None => {
+ // Letterpress underlay: a translucent white copy offset
+ // down-right BENEATH the glyphs — dark text keeps a lit
+ // edge on dark backdrops (the engraved-text treatment).
+ if self.text_relief > 0.0 {
+ pc.text_faded(text.clone(), *x + 0.75, *y + 0.75, *tsize, [255, 255, 255], self.text_relief, font.clone(), *bounds);
+ }
+ pc.text_with(text.clone(), *x, *y, *tsize, *color, font.clone(), *bounds)
+ }
}
}