Three things were wrong with it, and they compounded.
**The order was arbitrary** — orange, blue, pink, green, amber, violet, cyan,
rose jumped back and forth across the wheel, so it looked like a bag of
colours rather than a choice. It is sorted by hue now, one clean sweep, with
the degrees in the source so it stays that way when a colour is swapped. That
is also the order creation hands them out in, so someone making profiles one
after another walks the spectrum.
**The layout fought the form.** A fixed-size grid centred in the dialog
floated free of the left-aligned labels above it; distributed across the full
width the swatches stopped looking related to each other; and eight colours
wrapped to a short second row that read as the grid running out. Each row now
FILLS the width with its swatches sharing it equally, so the palette's edges
line up with the name field's and both rows are the same length. The palette
gained two hues to make that work: ten divides by five, eight didn't divide by
anything useful.
**Selection was a heavier circle.** A border drawn on the swatch's own edge
reads as a thicker ring, not as "this one". It is a ring OUTSIDE the disc with
a gap, plus a check — which also means the selection survives a reader who
can't tell two of these hues apart. The ring's space is always reserved, so
picking never nudges the grid.
Rust-heavy client model (like punktfunk-client-linux): a new cdylib crate
crates/punktfunk-android links punktfunk-core and exposes the JNI seam;
Kotlin (clients/android) owns only the Android-framework surface. Kotlin can't
import the C header the way Swift can, so the bridge is written in Rust to reuse
the Linux client's orchestration rather than re-port it.
- crates/punktfunk-android: JNI bridge — abiVersion/coreVersion native-link
proof + session connect/close handle; plane pumps stubbed for M4 stage 1.
- clients/android: Gradle project — :app (Compose) + :kit (Android library with
a cargo-ndk Exec task -> jniLibs). AGP 9.2 / Gradle 9.4.1 / Kotlin 2.3.21 /
Compose BOM 2026.05.01 / compileSdk 37 / targetSdk 36 / minSdk 31, shipping
arm64-v8a + x86_64. Phone + TV (leanback) installable. README rewritten.
- .gitea/workflows/android.yml: CI mirroring apple.yml on a Linux runner.
- punktfunk-core: switch rcgen to the ring backend so the whole quic tree is
aws-lc-free (smaller client .so, cmake-free cross-compile; a win for all targets).
Validated on this box: :app:assembleDebug -> APK with both ABIs; emulator
first-light renders the bridge linked (core ABI v2) with logcat confirmation;
clippy -D warnings + cargo fmt clean; core tests green on the ring backend.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>