From 02407e0f7ab044d6fd19600c644cc6ea2e18e9af Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 3 Feb 2026 19:02:47 +0000 Subject: [PATCH] fix(ui): restore dark tab and tool output styling Use tokenized border contrast so dark mode borders stay subtle, keep instance tab status dots vivid in dark themes, and adjust tool-call code block header background via a dedicated token. --- .../ui/src/styles/messaging/message-base.css | 4 +-- .../ui/src/styles/messaging/tool-call.css | 14 ++++++-- packages/ui/src/styles/panels/tabs.css | 32 +++++++++++++++++++ packages/ui/src/styles/tokens.css | 18 +++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/packages/ui/src/styles/messaging/message-base.css b/packages/ui/src/styles/messaging/message-base.css index 5f329d19..13b3551c 100644 --- a/packages/ui/src/styles/messaging/message-base.css +++ b/packages/ui/src/styles/messaging/message-base.css @@ -175,7 +175,7 @@ .message-reasoning { @apply my-2 border rounded; - --reasoning-border-color: color-mix(in oklab, var(--border-base) 62%, var(--text-primary)); + --reasoning-border-color: var(--border-strong, var(--border-base)); border-color: var(--reasoning-border-color); background-color: var(--surface-secondary); color: inherit; @@ -287,7 +287,7 @@ } .message-reasoning-card { - --reasoning-border-color: color-mix(in oklab, var(--border-base) 62%, var(--text-primary)); + --reasoning-border-color: var(--border-strong, var(--border-base)); background-color: var(--message-assistant-bg); border-left: 4px solid var(--message-assistant-border); margin-top: 0; diff --git a/packages/ui/src/styles/messaging/tool-call.css b/packages/ui/src/styles/messaging/tool-call.css index 38bfd1f4..6270e536 100644 --- a/packages/ui/src/styles/messaging/tool-call.css +++ b/packages/ui/src/styles/messaging/tool-call.css @@ -66,8 +66,8 @@ .tool-call { @apply border overflow-hidden; - /* Tool-call output borders need more contrast in light mode. */ - --tool-call-border-color: color-mix(in oklab, var(--border-base) 62%, var(--text-primary)); + /* Tokenized so dark mode doesn't get overly bright borders. */ + --tool-call-border-color: var(--border-strong, var(--border-base)); border-color: var(--tool-call-border-color); color: inherit; --tool-call-line-unit: 1.4em; @@ -419,7 +419,7 @@ position: sticky; top: 0; z-index: auto; - background-color: color-mix(in oklab, var(--surface-secondary) 70%, var(--text-primary)); + background-color: var(--code-block-header-bg, var(--surface-secondary)); border-bottom: 1px solid var(--tool-call-border-color); box-shadow: none; } @@ -447,6 +447,14 @@ overflow-y: visible; } +/* Shiki injects inline background colors; force token surfaces. */ +.tool-call-markdown pre.shiki, +.tool-call-markdown pre.shiki code, +.tool-call-markdown .shiki { + background: transparent !important; + background-color: transparent !important; +} + .tool-call-markdown::-webkit-scrollbar { width: 8px; } diff --git a/packages/ui/src/styles/panels/tabs.css b/packages/ui/src/styles/panels/tabs.css index 50f3cb8a..76d37ce1 100644 --- a/packages/ui/src/styles/panels/tabs.css +++ b/packages/ui/src/styles/panels/tabs.css @@ -104,6 +104,38 @@ --session-status-dot: color-mix(in oklab, var(--session-status-permission-fg) 55%, var(--surface-base)); } +/* Dark mode: keep dots vivid (avoid muddy mixes). */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) .tab-base .status-indicator.session-status.session-working { + --session-status-dot: var(--session-status-working-fg); + } + :root:not([data-theme]) .tab-base .status-indicator.session-status.session-compacting { + --session-status-dot: var(--session-status-compacting-fg); + } + :root:not([data-theme]) .tab-base .status-indicator.session-status.session-idle { + --session-status-dot: var(--session-status-idle-fg); + } + :root:not([data-theme]) .tab-base .status-indicator.session-status.session-permission { + --session-status-dot: var(--session-status-permission-fg); + } +} + +[data-theme="dark"] .tab-base .status-indicator.session-status.session-working { + --session-status-dot: var(--session-status-working-fg); +} + +[data-theme="dark"] .tab-base .status-indicator.session-status.session-compacting { + --session-status-dot: var(--session-status-compacting-fg); +} + +[data-theme="dark"] .tab-base .status-indicator.session-status.session-idle { + --session-status-dot: var(--session-status-idle-fg); +} + +[data-theme="dark"] .tab-base .status-indicator.session-status.session-permission { + --session-status-dot: var(--session-status-permission-fg); +} + .new-tab-button { @apply inline-flex items-center justify-center w-8 h-8 rounded-md transition-colors; background-color: var(--new-tab-bg); diff --git a/packages/ui/src/styles/tokens.css b/packages/ui/src/styles/tokens.css index 19edbf6a..794a3843 100644 --- a/packages/ui/src/styles/tokens.css +++ b/packages/ui/src/styles/tokens.css @@ -11,6 +11,7 @@ --border-base: #e0e0e0; --border-secondary: #e0e0e0; --border-muted: #e0e0e0; + --border-strong: color-mix(in oklab, var(--border-base) 62%, var(--text-primary)); /* Text tokens */ --text-primary: #111827; @@ -81,6 +82,7 @@ --panel-shadow: 0 6px 24px rgba(0, 0, 0, 0.12); --panel-shadow-strong: 0 12px 32px rgba(0, 0, 0, 0.18); --popover-shadow: 0 16px 40px rgba(0, 0, 0, 0.18); + --code-block-header-bg: color-mix(in oklab, var(--surface-secondary) 78%, var(--text-primary)); --message-error-bg: rgba(244, 67, 54, 0.1); --message-error-bg-strong: rgba(244, 67, 54, 0.15); --danger-soft-bg: rgba(239, 68, 68, 0.1); @@ -182,6 +184,7 @@ --border-base: #3a3a3a; --border-secondary: #3a3a3a; --border-muted: #3a3a3a; + --border-strong: var(--border-base); /* Text tokens */ --text-primary: #cfd4dc; @@ -248,6 +251,7 @@ --panel-shadow: 0 6px 24px rgba(0, 0, 0, 0.35); --panel-shadow-strong: 0 12px 32px rgba(0, 0, 0, 0.45); --popover-shadow: 0 16px 40px rgba(0, 0, 0, 0.55); + --code-block-header-bg: var(--surface-secondary); --border-critical: var(--status-error); --timeline-segment-active-bg: #0f5b44; --timeline-segment-active-text: #ffffff; @@ -346,6 +350,7 @@ --border-base: #3a3a3a; --border-secondary: #3a3a3a; --border-muted: #3a3a3a; + --border-strong: var(--border-base); /* Text tokens */ --text-primary: #cfd4dc; @@ -412,6 +417,7 @@ --panel-shadow: 0 6px 24px rgba(0, 0, 0, 0.35); --panel-shadow-strong: 0 12px 32px rgba(0, 0, 0, 0.45); --popover-shadow: 0 16px 40px rgba(0, 0, 0, 0.55); + --code-block-header-bg: var(--surface-secondary); --border-critical: var(--status-error); --timeline-segment-active-bg: #0f5b44; --timeline-segment-active-text: #ffffff; @@ -430,6 +436,18 @@ --kbd-bg: var(--surface-secondary); --kbd-border: var(--border-base); --kbd-text: var(--text-primary); + --button-primary-bg: #3f3f46; + --button-primary-hover-bg: #52525b; + --button-primary-text: #f5f6f8; + --tab-active-bg: #3f3f46; + --tab-active-hover-bg: #52525b; + --tab-active-text: #f5f6f8; + --tab-inactive-bg: #2a2a31; + --tab-inactive-hover-bg: #3f3f46; + --tab-inactive-text: #d4d4d8; + --new-tab-bg: #3f3f46; + --new-tab-hover-bg: #52525b; + --new-tab-text: #f5f6f8; /* Layout & spacing tokens */ --space-2xs: 2px;