Palette override in a light media query; scanlines, vignette, card
shadow and signal glows moved to tokens/color-mix so both prints share
one set of rules. color-scheme on :root brings UA scrollbars and form
controls along.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every video tile is built client-side via document.createElement, never
parsed from HTML - browsers only seed the live .muted property from the
muted attribute for parser-inserted elements, so the attribute alone
never actually silenced the local preview. Result: your own mic played
back through your own speakers even with no other peers in the call.
Now sets el.set_muted(true) directly whenever the preview's srcObject
is (re)assigned.
The SSR branch rendered an empty call-panel div while the hydrate
branch expected a child button node. On any full load/refresh of the
lobby room, the mismatched hydration cursor hit tachys's
unreachable!() panic path, trapping the wasm instance and killing all
reactivity (routing, room switching, SSE) for the rest of the page
load, while the already-rendered SSR HTML stayed visually intact.
SSR now renders the same default join-button markup hydrate expects.
Building cargo-leptos from source pulls in swc/lightningcss/rhai and was
OOM-killing the aarch64 (Raspberry Pi) runner. cargo-leptos publishes
prebuilt aarch64-unknown-linux-gnu binaries, so binstall sidesteps the
compile entirely.
Mesh calling's nested Show/For inside ChatShell's own Show inlined as a
type parameter, blowing rustc's query recursion limit during the wasm
release build (CI: "queries overflow the depth limit!"). Splitting the
in-call view into its own component and type-erasing both CallPanel
branches with .into_any() keeps the type shallow instead of raising the
crate-wide limit.
Rooms can now require a Kanidm group (via the `groups` OIDC claim,
mapped by `oauth2 update-claim-map` server-side) - dev/ops require
`developers`, enforced at every message path (send, history, SSE).
Adds a minimal WebRTC mesh call feature scoped to the lobby room,
signaled over a separate `call.room.*` NATS subject kept out of the
chat archive: public STUN only, no TURN, no SFU - small groups on
friendly networks, by design.
async_nats::connect() silently drops user:pass embedded in NATS_URL,
so the server rejected every connection with an authorization violation.
Parse the URL and feed credentials through ConnectOptions instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirrors the gpupaper release convention: v* tags build x86_64/aarch64
tarballs (binary + leptos site + systemd unit), upload them as Gitea
release assets, push bendik/cnats to Docker Hub, and update the AUR
package with checksums from the release assets.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DATABASE_URL required at startup; schema self-initializes.
Compose gains a postgres service for standalone dev.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Initial import plus deployment packaging: multi-stage Dockerfile
(cargo-leptos build -> debian-slim runtime), .dockerignore, and a
dev-only docker-compose (app + local NATS). Production deployment
lives in the infrastructure repo.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>