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"> <div data-testid="lane-changes-browse">
{/* Pinned: the finder is what you reach for after scrolling a {/* Pinned: the finder is what you reach for after scrolling a
long tree, not only from its top. */} 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 <input
value={query} value={query}
onChange={(e) => setQuery(e.target.value)} onChange={(e) => setQuery(e.target.value)}
@@ -1320,7 +1320,7 @@ export function LaneChangesPanel({
{(stagedCount > 0 || toStage.length > 0) && ( {(stagedCount > 0 || toStage.length > 0) && (
<div <div
data-testid="lane-changes-actions" 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. */} {/* ONE row: message, commit, then the two bulk index moves. */}
{stagedCount > 0 && ( {stagedCount > 0 && (
@@ -276,10 +276,7 @@ export function LaneGitHeader({
</> </>
); );
return ( return (
<div <div data-testid="lane-git-header" className="mb-2 border-b border-border pb-1.5">
data-testid="lane-git-header"
className="mb-2 rounded-md border border-border bg-surface-2 px-2 py-1"
>
<LaneGitBar <LaneGitBar
laneId={laneId} laneId={laneId}
session={session} session={session}
@@ -86,7 +86,7 @@ export function SessionReplay({
<div className="min-h-0 flex-1 overflow-hidden"> <div className="min-h-0 flex-1 overflow-hidden">
<ConversationView sessionId={sessionId} /> <ConversationView sessionId={sessionId} />
</div> </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 <PromptEditor
bare bare
images={images} images={images}
@@ -24,9 +24,9 @@ const vars: Record<string, string> = {
describe("buildTerminalTheme", () => { describe("buildTerminalTheme", () => {
it("maps theme tokens onto the xterm palette", () => { it("maps theme tokens onto the xterm palette", () => {
const t = buildTerminalTheme((n) => vars[n] ?? ""); const t = buildTerminalTheme((n) => vars[n] ?? "");
// The card's colour, so the terminal blends into the card it sits on. // The page's colour: the console sits on the page, with no card or frame.
expect(t.background).toBe("#272a2d"); expect(t.background).toBe("#111113");
expect(t.cursorAccent).toBe("#272a2d"); expect(t.cursorAccent).toBe("#111113");
expect(t.foreground).toBe("#edeef0"); expect(t.foreground).toBe("#edeef0");
expect(t.cursor).toBe("#edeef0"); expect(t.cursor).toBe("#edeef0");
expect(t.selectionBackground).toBe("#43484e"); expect(t.selectionBackground).toBe("#43484e");
@@ -60,7 +60,7 @@ describe("buildTerminalTheme", () => {
describe("terminalThemeFor", () => { describe("terminalThemeFor", () => {
it("resolves variables on a dark probe scoped to the theme id, then removes it", () => { it("resolves variables on a dark probe scoped to the theme id, then removes it", () => {
const style = document.createElement("style"); 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); document.head.appendChild(style);
try { try {
expect(terminalThemeFor("default").background).toBe("#010203"); expect(terminalThemeFor("default").background).toBe("#010203");
+3 -3
View File
@@ -54,11 +54,11 @@ export function buildTerminalTheme(read: VarReader): ITheme {
const magenta = "#c678dd"; const magenta = "#c678dd";
const cyan = "#56b6c2"; const cyan = "#56b6c2";
return { return {
// The `.card` colour: the console sits on a card, with no frame between. // The page's colour: the console sits on the page, with no card or frame.
background: v("--surface-3"), background: v("--surface-0"),
foreground: v("--fg-primary"), foreground: v("--fg-primary"),
cursor: v("--fg-primary"), cursor: v("--fg-primary"),
cursorAccent: v("--surface-3"), cursorAccent: v("--surface-0"),
selectionBackground: v("--border-light"), selectionBackground: v("--border-light"),
black: v("--border-light"), black: v("--border-light"),
red, red,
+5 -3
View File
@@ -621,7 +621,7 @@ export function Workspace() {
<div className={`flex min-h-0 flex-1 gap-4${home ? " hidden" : ""}`}> <div className={`flex min-h-0 flex-1 gap-4${home ? " hidden" : ""}`}>
<section <section
data-testid="lane-detail" 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" : "" currentLane && changesOpen && changesSize === "full" ? " hidden" : ""
}`} }`}
> >
@@ -795,7 +795,9 @@ export function Workspace() {
<aside <aside
id="lane-changes-panel" id="lane-changes-panel"
data-testid="lane-changes-card" 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. */} {/* Activity bar: Files · Changes · Sessions, then the resize control. */}
<div className="mb-2 flex items-center gap-1" role="toolbar"> <div className="mb-2 flex items-center gap-1" role="toolbar">
@@ -891,7 +893,7 @@ export function Workspace() {
aria-controls="lane-changes-panel" aria-controls="lane-changes-panel"
aria-label={tLanes("changes.expand")} aria-label={tLanes("changes.expand")}
title={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" /> <PanelLeftClose className="h-4 w-4" />
<span className="text-[10px] uppercase tracking-wide [writing-mode:vertical-rl]"> <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" class="flex min-h-0 flex-1 gap-4"
> >
<section <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" data-testid="lane-detail"
> >
<div <div