Establish a distinct workbench visual frame
Why: Spacing-only refinements still looked like the original flat gray workspace and did not satisfy the approved visual redesign. Evidence: 272 unit tests, 16 browser scenarios across 320-1920px, and the production build pass locally. Impact: Gives navigation, authored messages, assistant results, and work details clearly different visual surfaces while preserving behavior. Refs: Agent-System-Dev feature/workbench-visual-redesign
This commit is contained in:
@@ -159,6 +159,34 @@ test('uses a focused reading column and a compact authored-message shape', async
|
||||
expect(authoredBox!.width).toBeLessThanOrEqual(680)
|
||||
expect(authoredBox!.x + authoredBox!.width).toBeCloseTo(answerBox!.x + answerBox!.width, 0)
|
||||
|
||||
const surfaces = await page.evaluate(() => {
|
||||
const pick = (selector: string) => {
|
||||
const element = document.querySelector(selector)
|
||||
if (!element) throw new Error(`missing ${selector}`)
|
||||
const style = getComputedStyle(element)
|
||||
return {
|
||||
background: style.backgroundColor,
|
||||
color: style.color,
|
||||
borderRadius: Number.parseFloat(style.borderRadius),
|
||||
paddingLeft: Number.parseFloat(style.paddingLeft),
|
||||
}
|
||||
}
|
||||
return {
|
||||
chrome: pick('.companion-topbar'),
|
||||
context: pick('.left-nav'),
|
||||
conversation: pick('.main'),
|
||||
answer: pick('.msg.assistant'),
|
||||
authored: pick('.msg.user .bubble'),
|
||||
}
|
||||
})
|
||||
const rgb = (value: string) => value.match(/[\d.]+/g)?.slice(0, 3).map(Number) ?? [0, 0, 0]
|
||||
const distance = (a: string, b: string) => rgb(a).reduce((sum, value, index) => sum + Math.abs(value - rgb(b)[index]), 0)
|
||||
expect(distance(surfaces.chrome.background, surfaces.conversation.background)).toBeGreaterThan(300)
|
||||
expect(distance(surfaces.context.background, surfaces.conversation.background)).toBeGreaterThan(300)
|
||||
expect(distance(surfaces.authored.background, surfaces.answer.background)).toBeGreaterThan(300)
|
||||
expect(surfaces.answer.borderRadius).toBeGreaterThanOrEqual(12)
|
||||
expect(surfaces.answer.paddingLeft).toBeGreaterThanOrEqual(20)
|
||||
|
||||
const activeCard = page.locator('.right-panel .acard.status-active')
|
||||
await expect(activeCard).toBeVisible()
|
||||
const cardStyle = await activeCard.evaluate(element => {
|
||||
|
||||
@@ -57,6 +57,13 @@
|
||||
margin-right: max(0px, calc((100% - 840px) / 2));
|
||||
margin-left: auto;
|
||||
}
|
||||
.work-companion-chat .chat-body > .msg.assistant {
|
||||
padding: 20px 24px 16px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-xl);
|
||||
background: var(--bg-raised);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
.work-companion-chat .msg-role {
|
||||
margin-bottom: 10px;
|
||||
color: var(--text-dim);
|
||||
@@ -131,10 +138,12 @@
|
||||
|
||||
.work-companion-chat .msg.user .bubble {
|
||||
padding: 14px 18px;
|
||||
background: var(--bg-active);
|
||||
border: 1px solid var(--border-soft);
|
||||
background: var(--primary);
|
||||
border: 1px solid var(--primary);
|
||||
border-radius: var(--radius-lg) var(--radius-lg) var(--radius-xs) var(--radius-lg);
|
||||
color: var(--primary-foreground);
|
||||
line-height: 1.7;
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
.work-companion-chat .process-collapse {
|
||||
margin: 12px 0 16px;
|
||||
|
||||
+55
-11
@@ -3,12 +3,48 @@
|
||||
height: 100dvh;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
--companion-chrome: var(--primary);
|
||||
--companion-chrome-text: var(--primary-foreground);
|
||||
--companion-chrome-dim: color-mix(in srgb, var(--primary-foreground) 72%, transparent);
|
||||
--companion-chrome-faint: color-mix(in srgb, var(--primary-foreground) 52%, transparent);
|
||||
--companion-chrome-hover: color-mix(in srgb, var(--primary-foreground) 9%, transparent);
|
||||
--companion-chrome-active: color-mix(in srgb, var(--primary-foreground) 15%, transparent);
|
||||
}
|
||||
[data-theme='dark'] .app.companion-app {
|
||||
--companion-chrome: var(--bg-panel);
|
||||
--companion-chrome-text: var(--text);
|
||||
--companion-chrome-dim: var(--text-dim);
|
||||
--companion-chrome-faint: var(--text-faint);
|
||||
--companion-chrome-hover: var(--bg-hover);
|
||||
--companion-chrome-active: var(--bg-active);
|
||||
}
|
||||
[data-theme='molv'] .app.companion-app {
|
||||
--companion-chrome: var(--bg-sidebar);
|
||||
--companion-chrome-text: var(--text-sidebar);
|
||||
--companion-chrome-dim: var(--text-sidebar-dim);
|
||||
--companion-chrome-faint: var(--text-sidebar-faint);
|
||||
--companion-chrome-hover: var(--bg-hover);
|
||||
--companion-chrome-active: var(--bg-active);
|
||||
}
|
||||
|
||||
.companion-app .app-body { min-width: 0; overflow: hidden; }
|
||||
.companion-app .left-nav,
|
||||
.companion-app .main,
|
||||
.companion-app .right-panel { min-height: 0; max-width: 100%; overflow: hidden; }
|
||||
.companion-app .left-nav,
|
||||
.companion-app .companion-topbar {
|
||||
--text: var(--companion-chrome-text);
|
||||
--text-dim: var(--companion-chrome-dim);
|
||||
--text-faint: var(--companion-chrome-faint);
|
||||
--bg-hover: var(--companion-chrome-hover);
|
||||
--bg-active: var(--companion-chrome-active);
|
||||
--border: var(--companion-chrome-active);
|
||||
--border-soft: var(--companion-chrome-hover);
|
||||
--border-strong: var(--companion-chrome-dim);
|
||||
background: var(--companion-chrome);
|
||||
color: var(--companion-chrome-text);
|
||||
border-color: var(--companion-chrome-hover);
|
||||
}
|
||||
.companion-app .left-nav { transition: none; }
|
||||
.companion-app .left-nav[hidden],
|
||||
.companion-app .right-panel[hidden],
|
||||
@@ -66,8 +102,8 @@
|
||||
.companion-app .right-panel .acard-summary-row p,
|
||||
.companion-app .right-panel .acard-findings li { color: var(--text); font-size: var(--fs-ui-base); }
|
||||
.companion-topbar .brand-mark {
|
||||
background: var(--primary-sidebar);
|
||||
color: var(--primary-sidebar-foreground);
|
||||
background: var(--companion-chrome-text);
|
||||
color: var(--companion-chrome);
|
||||
box-shadow: none;
|
||||
border-radius: var(--radius-sm) !important;
|
||||
}
|
||||
@@ -83,22 +119,22 @@
|
||||
border: none;
|
||||
border-radius: var(--radius-sm);
|
||||
background: none;
|
||||
color: var(--text-sidebar-dim);
|
||||
color: var(--companion-chrome-dim);
|
||||
font-size: var(--fs-ui-caption);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.shell-nav-button:hover,
|
||||
.shell-return:hover { background: var(--bg-hover); color: var(--text-sidebar); }
|
||||
.shell-nav-button[aria-pressed='true'] { background: var(--bg-active); color: var(--text-sidebar); }
|
||||
.shell-return:hover { background: var(--companion-chrome-hover); color: var(--companion-chrome-text); }
|
||||
.shell-nav-button[aria-pressed='true'] { background: var(--companion-chrome-active); color: var(--companion-chrome-text); }
|
||||
.shell-nav-button svg,
|
||||
.shell-return svg { flex: none; }
|
||||
.shell-back-icon { transform: rotate(180deg); }
|
||||
.shell-pending {
|
||||
padding: 0 4px;
|
||||
border-radius: var(--radius-xs);
|
||||
background: var(--bg-active);
|
||||
color: var(--text-sidebar);
|
||||
background: var(--companion-chrome-active);
|
||||
color: var(--companion-chrome-text);
|
||||
font-size: var(--fs-ui-xs);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
@@ -110,11 +146,19 @@
|
||||
.companion-app .tsb-projrow-stage { max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-dim); border-radius: var(--radius-sm); }
|
||||
.companion-app .tsb-iconbtn { width: 32px; height: 32px; flex: none; }
|
||||
.companion-app .tsb-actions { padding: 12px 14px; gap: 10px; }
|
||||
.companion-app .tsb-newtask { min-height: 40px; height: auto; box-shadow: none; transition: none; }
|
||||
.companion-app .tsb-newtask {
|
||||
min-height: 40px;
|
||||
height: auto;
|
||||
background: var(--companion-chrome-text);
|
||||
color: var(--companion-chrome);
|
||||
box-shadow: none;
|
||||
transition: none;
|
||||
}
|
||||
.companion-app .tsb-newtask:hover { background: color-mix(in srgb, var(--companion-chrome-text) 90%, var(--companion-chrome)); }
|
||||
.companion-app .tsb-newtask-main { justify-content: center; padding: 8px 12px; }
|
||||
.companion-app .tsb-newtask-caret { width: 36px; flex: none; }
|
||||
.companion-app .tsb-search { min-height: 38px; height: auto; padding: 8px 12px; background: var(--bg-hover); border-color: transparent; }
|
||||
.companion-app .tsb-search:focus-within { background: var(--bg-panel); }
|
||||
.companion-app .tsb-search { min-height: 38px; height: auto; padding: 8px 12px; background: var(--companion-chrome-hover); border-color: var(--companion-chrome-hover); }
|
||||
.companion-app .tsb-search:focus-within { background: var(--companion-chrome-active); border-color: var(--companion-chrome-dim); }
|
||||
.companion-app .tsb-orgrow { padding: 4px 16px 8px; }
|
||||
.companion-app .tsb-seclabel { color: var(--text-dim); font-size: var(--fs-ui-sm); font-weight: 600; }
|
||||
.companion-app .tsb-scroll { padding: 0 8px 12px; }
|
||||
@@ -154,7 +198,7 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
.companion-app .tsb-row-menu:hover { background: var(--bg-hover); color: var(--text); }
|
||||
.companion-app .tsb-bottom { padding: 10px 12px; gap: 4px; background: var(--bg-hover); }
|
||||
.companion-app .tsb-bottom { padding: 10px 12px; gap: 4px; background: var(--companion-chrome-hover); }
|
||||
.companion-app .tsb-tool { min-height: 38px; padding: 7px 10px; }
|
||||
.companion-app .tsb-avatar { background: var(--bg-active); color: var(--text); box-shadow: none; border-radius: var(--radius-full); }
|
||||
.companion-app .tsb-user-sub { color: var(--text-dim); }
|
||||
|
||||
Reference in New Issue
Block a user