feat(workspace): session view and right panel sit on the page, no cards

The session section and the Files/Changes panel drop their cards; one
vertical divider separates them (none at full width), and the collapsed
rail keeps only that divider. The terminal goes back to the page colour
(--surface-0), and the panel's two sticky bars cover scrolled content in
the page colour instead of the card's.

Inside, the git row loses its bordered box for a bottom divider, and the
ended-session prompt box drops its own fill and shadow.
This commit is contained in:
2026-10-03 13:33:22 +07:00
parent 8f6360f993
commit 1597c110d4
7 changed files with 17 additions and 18 deletions
@@ -984,7 +984,7 @@ export function LaneChangesPanel({
<div data-testid="lane-changes-browse">
{/* Pinned: the finder is what you reach for after scrolling a
long tree, not only from its top. */}
<div className="sticky top-0 z-10 flex items-center gap-1.5 bg-surface-3 pb-2">
<div className="sticky top-0 z-10 flex items-center gap-1.5 bg-surface-0 pb-2">
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
@@ -1320,7 +1320,7 @@ export function LaneChangesPanel({
{(stagedCount > 0 || toStage.length > 0) && (
<div
data-testid="lane-changes-actions"
className="sticky top-0 z-10 mb-1.5 flex items-center gap-1.5 border-b border-border-light bg-surface-3 pb-2"
className="sticky top-0 z-10 mb-1.5 flex items-center gap-1.5 border-b border-border-light bg-surface-0 pb-2"
>
{/* ONE row: message, commit, then the two bulk index moves. */}
{stagedCount > 0 && (
@@ -276,10 +276,7 @@ export function LaneGitHeader({
</>
);
return (
<div
data-testid="lane-git-header"
className="mb-2 rounded-md border border-border bg-surface-2 px-2 py-1"
>
<div data-testid="lane-git-header" className="mb-2 border-b border-border pb-1.5">
<LaneGitBar
laneId={laneId}
session={session}
@@ -86,7 +86,7 @@ export function SessionReplay({
<div className="min-h-0 flex-1 overflow-hidden">
<ConversationView sessionId={sessionId} />
</div>
<div className="rounded-2xl border border-border bg-surface-1 p-2 shadow-sm transition-colors focus-within:border-accent/50">
<div className="rounded-2xl border border-border p-2 transition-colors focus-within:border-accent/50">
<PromptEditor
bare
images={images}
@@ -24,9 +24,9 @@ const vars: Record<string, string> = {
describe("buildTerminalTheme", () => {
it("maps theme tokens onto the xterm palette", () => {
const t = buildTerminalTheme((n) => vars[n] ?? "");
// The card's colour, so the terminal blends into the card it sits on.
expect(t.background).toBe("#272a2d");
expect(t.cursorAccent).toBe("#272a2d");
// The page's colour: the console sits on the page, with no card or frame.
expect(t.background).toBe("#111113");
expect(t.cursorAccent).toBe("#111113");
expect(t.foreground).toBe("#edeef0");
expect(t.cursor).toBe("#edeef0");
expect(t.selectionBackground).toBe("#43484e");
@@ -60,7 +60,7 @@ describe("buildTerminalTheme", () => {
describe("terminalThemeFor", () => {
it("resolves variables on a dark probe scoped to the theme id, then removes it", () => {
const style = document.createElement("style");
style.textContent = `.dark { --surface-3: 1 2 3; } .dark[data-theme="darcula"] { --surface-3: 30 31 32; }`;
style.textContent = `.dark { --surface-0: 1 2 3; } .dark[data-theme="darcula"] { --surface-0: 30 31 32; }`;
document.head.appendChild(style);
try {
expect(terminalThemeFor("default").background).toBe("#010203");
+3 -3
View File
@@ -54,11 +54,11 @@ export function buildTerminalTheme(read: VarReader): ITheme {
const magenta = "#c678dd";
const cyan = "#56b6c2";
return {
// The `.card` colour: the console sits on a card, with no frame between.
background: v("--surface-3"),
// The page's colour: the console sits on the page, with no card or frame.
background: v("--surface-0"),
foreground: v("--fg-primary"),
cursor: v("--fg-primary"),
cursorAccent: v("--surface-3"),
cursorAccent: v("--surface-0"),
selectionBackground: v("--border-light"),
black: v("--border-light"),
red,
+5 -3
View File
@@ -621,7 +621,7 @@ export function Workspace() {
<div className={`flex min-h-0 flex-1 gap-4${home ? " hidden" : ""}`}>
<section
data-testid="lane-detail"
className={`flex min-h-0 min-w-0 flex-1 flex-col ${currentLane ? "card p-4" : ""}${
className={`flex min-h-0 min-w-0 flex-1 flex-col${
currentLane && changesOpen && changesSize === "full" ? " hidden" : ""
}`}
>
@@ -795,7 +795,9 @@ export function Workspace() {
<aside
id="lane-changes-panel"
data-testid="lane-changes-card"
className={`card flex shrink-0 flex-col p-3 ${CHANGES_WIDTH[changesSize]}`}
className={`flex shrink-0 flex-col ${CHANGES_WIDTH[changesSize]}${
changesSize === "full" ? "" : " border-l border-border pl-4"
}`}
>
{/* Activity bar: Files · Changes · Sessions, then the resize control. */}
<div className="mb-2 flex items-center gap-1" role="toolbar">
@@ -891,7 +893,7 @@ export function Workspace() {
aria-controls="lane-changes-panel"
aria-label={tLanes("changes.expand")}
title={tLanes("changes.expand")}
className="card flex w-9 shrink-0 flex-col items-center gap-2 py-3 text-fg-muted transition-colors hover:text-fg-primary"
className="flex w-9 shrink-0 flex-col items-center gap-2 border-l border-border py-3 text-fg-muted transition-colors hover:text-fg-primary"
>
<PanelLeftClose className="h-4 w-4" />
<span className="text-[10px] uppercase tracking-wide [writing-mode:vertical-rl]">
@@ -5400,7 +5400,7 @@ exports[`screen snapshots > Run 1`] = `
class="flex min-h-0 flex-1 gap-4"
>
<section
class="flex min-h-0 min-w-0 flex-1 flex-col "
class="flex min-h-0 min-w-0 flex-1 flex-col"
data-testid="lane-detail"
>
<div