Left rail restructure + Computer panel as a right-anchored overlay

PART 2 — panel positioning (the 'pushes the chat left' root cause):
DevicePanel was an in-flow flex sibling, so opening it consumed width and
shoved the chat. Now phone/tablet anchor it as an ABSOLUTE right-edge
overlay (md:absolute right-0 top-0 h-full z-30, w-[448px]/w-[550px]) so
the chat keeps full width and does NOT reflow; only 'full' stays in-flow
(grow-[4]) and lets the chat shrink. The chat row is now relative; the
aside is pointer-events-none with the screen card pointer-events-auto so
the header toggles/close stay clickable under the overlay's transparent
top padding. Verified live: composer.left is identical (472px) panel
open vs closed in tablet — the chat no longer shifts.

PART 1 — left rail:
- Logo in its own 80px header row as a 48px black rounded-2xl brand tile
  with a coral PawPrint mark (our placeholder logo) + sr-only 'clawmates'.
- Agent tiles bumped to 58px (Avatar 'rail' size + rounded-[20px]
  squircle), centered, gap-1, 2px coral active ring (rounded-[22px]).
- Hover-revealed ⋯ menu per agent row (new AgentRowMenu): a 176px #1A1A1A
  popover with Pin + Settings rows (coral 15px icons, 14px labels), closes
  on outside-click/Escape. Pin pins the claw to the top of the rail
  (persisted in localStorage, client-side); Settings deep-links to that
  claw's Computer → Settings (the claw redirect now forwards ?app=).

86 unit + 31 functional E2E green.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-11 05:26:09 -05:00
co-authored by Claude Fable 5
parent 9456edf198
commit 96e0134fc6
10 changed files with 280 additions and 69 deletions
@@ -4,16 +4,22 @@ import { createSession, fetchSessions } from "@/lib/api/sessions";
import { encodeSessionKeyParam } from "@/lib/url/session-key";
// Clicking a claw in the rail lands here: resume the most recent session,
// or open a fresh one (sessions are resumable, §6).
// or open a fresh one (sessions are resumable, §6). An optional ?app= is
// forwarded so the rail's per-claw "Settings" deep-link opens the Computer
// Settings app on landing.
export default async function ClawHome({
params,
searchParams,
}: {
params: Promise<{ clawId: string }>;
searchParams: Promise<{ app?: string }>;
}) {
const { clawId } = await params;
const { app } = await searchParams;
const sessions = await fetchSessions(clawId);
const target = sessions[0] ?? (await createSession(clawId));
const suffix = app ? `?app=${encodeURIComponent(app)}` : "";
redirect(
`/claws/${clawId}/chat/${encodeSessionKeyParam(target.sessionKey)}`,
`/claws/${clawId}/chat/${encodeSessionKeyParam(target.sessionKey)}${suffix}`,
);
}