Chat layout: roster, channel feed, composer

- The flock is a member list with live status (perched, flying,
  waiting on you, grounded); a scrolling strip on phones
- The Sentry and crows post into one channel; approvals are inline
  buttons on their messages; verdicts show as reactions
- "Who's flying" line above the composer; Ctrl/Cmd+Enter to send
- Consecutive messages from one author group under one name
- RIVE_CONTRACT.md: roster size and still message avatars

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UQnSw4RRWp8uqpj3nsnnXF
This commit is contained in:
SmokeyandClaude Opus 5.5 committed 2026-10-27 12:36:31 -06:00
1 parent d0ae4fd1c0
commit 0733ba1d9c
5 files changed
+346 -258

No files matched your search

+10
View File
@@ -28,6 +28,16 @@ const STAR = `<path d="M12 1.8 L14.9 8.6 L22.2 9.2 L16.6 14 L18.3 21.2 L12 17.4
const REACTION_MS: Record<Reaction, number> = { cheer: 800, sulk: 800, levelUp: 2000, levelDown: 1000, prank: 2500 };
// A still crow for message avatars. The live, animated crows live in the roster.
export function crowAvatar(role: Role): SVGSVGElement {
const svg = document.createElementNS(NS, "svg");
svg.setAttribute("viewBox", "0 0 352.23 324");
svg.setAttribute("class", `avatar crow-art role-${role}`);
svg.setAttribute("aria-hidden", "true");
svg.innerHTML = ART;
return svg;
}
export function svgCrow(name: string, role: Role): CrowView {
const el = document.createElement("figure");
el.className = `crow role-${role} pose-perched`;