From 4192a64c0fb03c825a9478ba7203ee95541aaef2 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 27 Apr 2026 22:42:44 -0400 Subject: [PATCH] =?UTF-8?q?feat(design):=20surface=20phase=20PR=203=20?= =?UTF-8?q?=E2=80=94=20Chat=20surface=20polish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the surface-phase spec for the Chat cluster (ChatView, ChatPanel, ChatMessage, ChatInputBar, ToolCallCard): Long-form line-height - ChatMessage: assistant-bubble .message-content jumps from 1.55 to 1.7 — chat is a reading surface, not a snippet stream. User bubbles stay tighter. - JournalView: dropped its :deep(.role-assistant .message-content) override; ChatMessage handles it now and Journal inherits. ToolCallCard borders - Removed the outer 1px border. ToolCallCard always renders inside an assistant bubble; the bubble already contains it. Background tint differentiates without re-bordering. Per the structural-not-decorative rule. - Error state preserved as a 3px left-edge accent in --color-danger, mirroring the assistant bubble's own left-edge pattern. Button reclassification per Hybrid rule - ChatView .bulk-link "All"/"None": accent text → --color-text-secondary (these are tertiary list-control affordances, not brand moments) - ChatView .bulk-delete-btn: --color-danger (Error terracotta) → --color-action-destructive (Oxblood) per Hybrid; paired with a Trash2 icon since destructive should always be reinforced by an icon, not just color - ChatView .btn-delete-conv hover: same Error → Oxblood swap - .btn-new-conv stays accent (brand moment, correct already) - .btn-send stays accent gradient (primary brand moment, foundation) Two-weights-only - Snapped every font-weight: 600/700 to 500 across ChatView, ChatPanel, ChatMessage, ToolCallCard per the doc rule. Co-Authored-By: Claude Opus 4.7 --- frontend/src/components/ChatMessage.vue | 10 ++++++-- frontend/src/components/ChatPanel.vue | 14 +++++------ frontend/src/components/ToolCallCard.vue | 17 ++++++++------ frontend/src/views/ChatView.vue | 30 +++++++++++++++--------- frontend/src/views/JournalView.vue | 6 ----- 5 files changed, 44 insertions(+), 33 deletions(-) diff --git a/frontend/src/components/ChatMessage.vue b/frontend/src/components/ChatMessage.vue index e62b06f..b449de0 100644 --- a/frontend/src/components/ChatMessage.vue +++ b/frontend/src/components/ChatMessage.vue @@ -155,7 +155,7 @@ const timingParts = computed((): string[] => { } .role-label { font-size: 0.75rem; - font-weight: 600; + font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em; } @@ -182,7 +182,7 @@ const timingParts = computed((): string[] => { .thinking-summary { padding: 0.25rem 0.5rem; font-size: 0.72rem; - font-weight: 600; + font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); @@ -215,6 +215,12 @@ details[open] .thinking-summary::before { overflow-y: auto; background: var(--color-bg-secondary); } +/* Long-form line-height (1.7) on assistant bubbles per the design system — + chat is a reading surface, not a snippet stream. User bubbles stay tighter. */ +.role-assistant .message-content { + line-height: 1.7; +} + .message-content { font-size: 0.95rem; line-height: 1.55; diff --git a/frontend/src/components/ChatPanel.vue b/frontend/src/components/ChatPanel.vue index 4a34c2d..70bb529 100644 --- a/frontend/src/components/ChatPanel.vue +++ b/frontend/src/components/ChatPanel.vue @@ -580,7 +580,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid padding: 0.15rem 0.1rem; font-family: inherit; font-size: 0.65rem; - font-weight: 700; + font-weight: 500; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-muted); @@ -598,7 +598,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid .context-sidebar-header .section-count { margin-left: auto; color: var(--color-text-muted); - font-weight: 600; + font-weight: 500; background: var(--color-bg); padding: 0.05rem 0.3rem; border-radius: 8px; @@ -622,7 +622,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid } .auto-pill { font-size: 0.55rem; - font-weight: 700; + font-weight: 500; letter-spacing: 0.05em; padding: 0.05rem 0.3rem; border-radius: 4px; @@ -686,7 +686,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-muted); - font-weight: 700; + font-weight: 500; margin-bottom: 0.2rem; } .queued-clear-row { @@ -734,7 +734,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid .empty-section-label { font-size: 0.7rem; - font-weight: 600; + font-weight: 500; text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-text-muted); @@ -871,7 +871,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid .btn-open-chat.prominent { font-size: 0.9rem; color: var(--color-primary); - font-weight: 600; + font-weight: 500; } .btn-clear-response { background: none; @@ -918,7 +918,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid :deep(.thinking-summary) { padding: 0.25rem 0.5rem; font-size: 0.72rem; - font-weight: 600; + font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); diff --git a/frontend/src/components/ToolCallCard.vue b/frontend/src/components/ToolCallCard.vue index 8eacc69..068755b 100644 --- a/frontend/src/components/ToolCallCard.vue +++ b/frontend/src/components/ToolCallCard.vue @@ -532,10 +532,13 @@ function closeEventSlideOver(changed = false) {