From 5d9085d5644815b5680f6b6645ab15401376ee4b Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 10 Mar 2026 15:02:39 -0400 Subject: [PATCH] =?UTF-8?q?UI:=20flip=20bubble=20hierarchy=20=E2=80=94=20r?= =?UTF-8?q?esponses=20elevated,=20prompts=20recessed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Design direction: "Illuminated Transcript" — the AI response is the primary artifact; user prompts are subordinate margin notes. ChatMessage.vue: - User bubble: ghosted background (rgba 3-4% opacity), muted text, thin near-invisible border. De-emphasized, recessed. - Assistant bubble: left indigo accent border (2px), elevated shadow via --color-bubble-asst-shadow. Commands attention. - Assistant role label: indigo (var(--color-primary)); user label muted. - Removed old white-override content rules (no longer on dark bg). - Thinking block: full border → left-only indigo accent bar (35% opacity), removed inner top border. ChatView.vue: - Streaming bubble: same left accent + shadow as assistant bubbles. - Streaming role label: indigo to match ChatMessage. - Thinking block in streaming: same treatment as ChatMessage. theme.css: - Added --color-bubble-user-bg/border/text for light + dark. - Added --color-bubble-asst-shadow for light + dark. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/assets/theme.css | 8 ++++++ frontend/src/components/ChatMessage.vue | 36 +++++++++---------------- frontend/src/views/ChatView.vue | 9 ++++--- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/frontend/src/assets/theme.css b/frontend/src/assets/theme.css index 0186a26..fcb2586 100644 --- a/frontend/src/assets/theme.css +++ b/frontend/src/assets/theme.css @@ -38,6 +38,10 @@ --color-input-bar-text: #1a1a1a; --color-input-bar-placeholder: rgba(0, 0, 0, 0.4); --color-overlay: rgba(0, 0, 0, 0.45); + --color-bubble-user-bg: rgba(0, 0, 0, 0.04); + --color-bubble-user-border: rgba(0, 0, 0, 0.08); + --color-bubble-user-text: #555566; + --color-bubble-asst-shadow: 0 2px 16px rgba(99, 102, 241, 0.10), 0 1px 4px rgba(0, 0, 0, 0.06); --radius-sm: 6px; --radius-md: 12px; --radius-lg: 18px; @@ -85,6 +89,10 @@ --color-input-bar-text: #e4e4f0; --color-input-bar-placeholder: rgba(228, 228, 240, 0.35); --color-overlay: rgba(0, 0, 0, 0.65); + --color-bubble-user-bg: rgba(255, 255, 255, 0.03); + --color-bubble-user-border: rgba(255, 255, 255, 0.07); + --color-bubble-user-text: #5a5a72; + --color-bubble-asst-shadow: 0 4px 28px rgba(99, 102, 241, 0.14), 0 2px 8px rgba(0, 0, 0, 0.4); } *, diff --git a/frontend/src/components/ChatMessage.vue b/frontend/src/components/ChatMessage.vue index cce26d2..365a965 100644 --- a/frontend/src/components/ChatMessage.vue +++ b/frontend/src/components/ChatMessage.vue @@ -121,13 +121,19 @@ const timingParts = computed((): string[] => { border-radius: 18px; } +/* User prompts: recessed, muted — margin notes */ .role-user .message-bubble { - background: linear-gradient(135deg, #6366f1, #4f46e5); - color: #fff; + background: var(--color-bubble-user-bg); + border: 1px solid var(--color-bubble-user-border); + color: var(--color-bubble-user-text); border-bottom-right-radius: 4px; } + +/* Assistant responses: elevated, lit — the primary text */ .role-assistant .message-bubble { background: var(--color-bg-card); + border-left: 2px solid var(--color-primary); + box-shadow: var(--color-bubble-asst-shadow); border-bottom-left-radius: 4px; } @@ -144,16 +150,17 @@ const timingParts = computed((): string[] => { letter-spacing: 0.03em; } .role-user .role-label { - color: rgba(255, 255, 255, 0.7); + color: var(--color-text-muted); + opacity: 0.6; } .role-assistant .role-label { - color: var(--color-text-muted); + color: var(--color-primary); } .thinking-block { margin-bottom: 0.5rem; - border: 1px solid var(--color-border); - border-radius: var(--radius-sm); + border-left: 2px solid rgba(129, 140, 248, 0.35); + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; overflow: hidden; } .thinking-summary { @@ -191,7 +198,6 @@ details[open] .thinking-summary::before { max-height: 300px; overflow-y: auto; background: var(--color-bg-secondary); - border-top: 1px solid var(--color-border); } .message-content { font-size: 0.95rem; @@ -202,22 +208,6 @@ details[open] .thinking-summary::before { margin-bottom: 0; } -/* User bubble content overrides for readability on primary bg */ -.role-user .message-content :deep(a) { - color: rgba(255, 255, 255, 0.9); - text-decoration: underline; -} -.role-user .message-content :deep(code) { - background: rgba(255, 255, 255, 0.15); - color: #fff; -} -.role-user .message-content :deep(pre) { - background: rgba(0, 0, 0, 0.2); -} -.role-user .message-content :deep(blockquote) { - border-left-color: rgba(255, 255, 255, 0.4); - color: rgba(255, 255, 255, 0.85); -} .message-actions { display: flex; diff --git a/frontend/src/views/ChatView.vue b/frontend/src/views/ChatView.vue index b632a68..6ad0fad 100644 --- a/frontend/src/views/ChatView.vue +++ b/frontend/src/views/ChatView.vue @@ -1222,6 +1222,8 @@ onUnmounted(() => { border-radius: 18px; border-bottom-left-radius: 4px; background: var(--color-bg-card); + border-left: 2px solid var(--color-primary); + box-shadow: var(--color-bubble-asst-shadow); } .streaming-bubble .message-header { display: flex; @@ -1231,7 +1233,7 @@ onUnmounted(() => { .streaming-bubble .role-label { font-size: 0.75rem; font-weight: 600; - color: var(--color-text-muted); + color: var(--color-primary); text-transform: uppercase; letter-spacing: 0.03em; } @@ -1258,8 +1260,8 @@ onUnmounted(() => { } .thinking-block { margin-bottom: 0.5rem; - border: 1px solid var(--color-border); - border-radius: var(--radius-sm); + border-left: 2px solid rgba(129, 140, 248, 0.35); + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; overflow: hidden; } .thinking-summary { @@ -1297,7 +1299,6 @@ details[open] .thinking-summary::before { max-height: 300px; overflow-y: auto; background: var(--color-bg-secondary); - border-top: 1px solid var(--color-border); } .streaming-status-dot { display: inline-block;