breadlock × breadgreet — style & motion sketch

Live CSS prototype of the lock screen and greeter, grounded in the real bread-theme tokens (fixed BOS dark base + pywal accents). The locker's software renderer (tiny-skia) can reproduce every motion here; the greeter uses the same CSS engine directly (GTK4). Badges mark what already ships vs what's proposed.

bg surface red green accent

Live stages click a state chip to replay it

The two apps should feel like one family: same palette, same radius/spacing tokens, same motion language (ease-out, 300–450ms).

breadlock

tiny-skia · 16ms timer loop · render.rs
21:47date
Friday · Aug 21

breadgreet

GTK4 · relm4 · CSS in theme.rs
21:47
bos — Hyprland icon

Motion library proposed animations, mapped to where each lands

Every idea below is prototypeable in CSS first, then ported. Effort: S small · M medium · L large (protocol/CPU work).

Entrance stagger S
21:47
Clock → pill → status cascade instead of one uniform fade. Pill overshoots ~2% (ease-out-back). Replaces the single overlay motion in render.rs.
Dot pop + caret S
Newest password dot scales in with overshoot; a blinking caret marks where you're typing. Today dots just appear — render.rs dot loop.
Wrong-password shake S
Wrong password
The classic, currently reserved for v2 — failure is just a red pill today. Damped 8px shake, red fill, auto-clear after fail_timeout_ms.
Success flash → unlock drift S
Correct password: green (color2) flash + glow ring, then the existing 400ms fade-and-drift-up unlock in state.rs.
Clock minute crossfade S
21:4721:48
300ms dip-and-swap on the minute tick instead of a hard blink. Locker: crossfade layer in render.rs. Greeter: GTK CSS transition.
Idle breathing S
Very subtle 3–4s sine on the pill's glow — proof the screen is live, not frozen. Cheap in render.rs; keep amplitude tiny (CPU is software-rendered).
Greeter card entrance S
Greeter currently has zero animation. Fade + 18px rise, staggered after the clock — GTK4 CSS @keyframes in breadgreet/theme.rs.
Entry focus ring S
Accent border + soft glow on focus, 200ms transition. Standard GTK CSS :focus — matches the shared stylesheet's "blue on focus" input rule.
Auth spinner S
Real gtk::Spinner during Stage::Working instead of static "Checking…" text. One widget swap in breadgreet/main.rs.
Session icon rows M
bos — Hyprland
Hyprland
sessions.rs doesn't parse Icon= today. Custom dropdown rows with per-session icons; falls back to a letter tile.
Wallpaper Ken Burns M
Slow pan on image wallpapers — just a drifting Transform in background.rs::paint, no new protocol. Gate behind config (CPU cost).

breadlock — where things land

  • Motion: extend the existing anim_timer/tick_animation loop in state.rs; add per-element progress fields (appear started per element, fail-shake start, dot-pop start).
  • Frame math: all easing lives in render.rs (ease_out_cubic, overlay_motion). Add ease_out_back for the pill overshoot and a damped sinusoid for the shake.
  • Success flash: reuse unlocking: Option<Instant> — flash phase 0–250ms, fade 250–650ms, then unlock().
  • Bigger: live blur-of-desktop needs a wlr-screencopy capture (already flagged v2 in README) — software downscale → blur → upscale to keep CPU sane. New [animation] config section (enabled / speed / per-effect toggles).

breadgreet — where things land

  • Motion: GTK4 CSS supports @keyframes/animation and transitions — everything goes in breadgreet/theme.rs::load_css, no Rust logic needed for entrance/focus/status.
  • Spinner: swap the status label for a gtk::Spinner during Stage::Working in main.rs.
  • Session icons: parse Icon= in sessions.rs and switch DropDown to custom rows.
  • Unify with the locker: same clock sizing/weight, same radius + spacing tokens; card backdrop-filter: blur() if GTK ≥ 4.12 supports it (README already requires 4.12).