retire the last light-theme branches and fix three latent color bugs

Dark is now the only theme, so every `.dark` selector matched
unconditionally while each non-dark branch was unreachable. That left
fourteen `.dark &` blocks sitting on top of token-based base rules and
silently overriding them with hardcoded grays from the previous palette
(#333333, #999999, #cccccc, #f2f2f2, #1f1f1f, #2a2a2a). Merged each value
down into its base rule and deleted the wrapper, then replaced fifteen
more legacy grays with the CYBER tokens.

Three bugs surfaced along the way:

- FileEditor read `documentElement.classList.contains('dark')`, but the
  `dark` class is bound on `.app-root`, so Monaco always loaded the
  light `vs` theme inside the dark editor surface.
- CodexLoginModal, CopilotLoginModal and NousLoginModal wrote
  `border-color: var(--arcoblue-6, #165dff)` and VoiceApiFormModal wrote
  `color: var(--primary-6, #18a058)`. Those Arco variables hold bare
  RGB triplets, not colors, so each declaration was invalid and
  discarded — the hover border and link color stayed stock Arco
  blue/green instead of the cyan accent.
- JourneyView drew the pinned-node ring in amber, a leftover from the
  old palette.

Rendering-layer only: no store logic, no /chat-run payload, no message
rendering path.
This commit is contained in:
2026-10-19 14:56:23 +08:00
parent f4f45304a6
commit 3debe903f7
26 changed files with 136 additions and 216 deletions
@@ -1355,10 +1355,6 @@ function isImage(type: string): boolean {
border-top: 0;
background-color: $bg-card;
flex-shrink: 0;
.dark & {
background-color: #333333;
}
}
.input-top-bar {
@@ -1383,7 +1379,7 @@ function isImage(type: string): boolean {
justify-content: center;
width: 16px;
height: 16px;
color: #999999;
color: $text-faint;
font-size: 12px;
svg {
@@ -1401,7 +1397,7 @@ function isImage(type: string): boolean {
display: inline-flex;
align-items: center;
justify-content: center;
color: #999999;
color: $text-faint;
width: 24px;
min-width: 24px;
height: 22px;
@@ -1418,12 +1414,12 @@ function isImage(type: string): boolean {
}
&.active {
color: #999999;
color: $text-faint;
opacity: 1;
}
&:hover {
color: #999999;
color: $text-faint;
opacity: 1;
}
}
@@ -1497,24 +1493,25 @@ function isImage(type: string): boolean {
.context-info {
font-size: 11px;
color: $text-muted;
color: $text-secondary;
min-width: 0;
white-space: nowrap;
&.context-warning {
color: #e8a735;
color: var(--warning);
}
}
.context-limit-editable {
cursor: pointer;
color: $text-secondary;
border-bottom: 1px dashed transparent;
transition: all 0.2s ease;
padding: 0 2px;
&:hover {
border-bottom-color: $text-muted;
background: rgba(128, 128, 128, 0.1);
border-bottom-color: rgba(var(--text-primary-rgb), 0.58);
background: rgba(var(--text-primary-rgb), 0.08);
border-radius: 2px;
}
}
@@ -1523,56 +1520,23 @@ function isImage(type: string): boolean {
width: 60px;
height: 4px;
margin-left: -4px;
background: rgba(128, 128, 128, 0.2);
background: rgba(var(--text-primary-rgb), 0.18);
border-radius: 2px;
overflow: hidden;
}
.context-bar-fill {
height: 100%;
background: linear-gradient(90deg, rgba(128, 128, 128, 0.3), rgba(128, 128, 128, 0.6));
background: linear-gradient(90deg, rgba(var(--text-primary-rgb), 0.42), rgba(var(--text-primary-rgb), 0.72));
border-radius: 2px;
transition: width 0.3s ease;
&.context-bar-warn {
background: linear-gradient(90deg, #c98a1a, #e8a735);
background: linear-gradient(90deg, rgba(var(--warning-rgb), 0.55), var(--warning));
}
&.context-bar-danger {
background: linear-gradient(90deg, #c43a2a, #e85d4a);
}
}
.dark .context-info {
color: rgba(255, 255, 255, 0.68);
&.context-warning {
color: #f0bc58;
}
}
.dark .context-limit-editable {
color: rgba(255, 255, 255, 0.8);
&:hover {
border-bottom-color: rgba(255, 255, 255, 0.58);
background: rgba(255, 255, 255, 0.08);
}
}
.dark .context-bar {
background: rgba(255, 255, 255, 0.18);
}
.dark .context-bar-fill {
background: linear-gradient(90deg, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0.72));
&.context-bar-warn {
background: linear-gradient(90deg, #d99d35, #f0bc58);
}
&.context-bar-danger {
background: linear-gradient(90deg, #d95445, #ff7a68);
background: linear-gradient(90deg, rgba(var(--error-rgb), 0.55), var(--error));
}
}
@@ -1715,7 +1679,7 @@ function isImage(type: string): boolean {
padding: 22px 12px 9px;
position: relative;
cursor: text;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.08);
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.32);
transition: border-color $transition-fast, box-shadow $transition-fast;
&:focus-within {
@@ -1727,11 +1691,6 @@ function isImage(type: string): boolean {
border-color: $accent-primary;
background-color: rgba(var(--accent-primary-rgb), 0.04);
}
.dark & {
background-color: #333333;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.32);
}
}
.resize-handle {
@@ -1838,16 +1797,12 @@ function isImage(type: string): boolean {
bottom: calc(100% + 8px);
max-height: 240px;
overflow-y: auto;
background: $bg-primary;
background: $bg-card;
border: 1px solid $border-color;
border-radius: $radius-sm;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.16);
z-index: 20;
padding: 4px;
.dark & {
background: #2a2a2a;
}
}
.slash-command-item {
@@ -278,15 +278,10 @@ defineExpose({
.history-loader-spinner {
width: 14px;
height: 14px;
border: 2px solid rgba(0, 0, 0, 0.16);
border: 2px solid rgba(var(--text-primary-rgb), 0.18);
border-top-color: $accent-primary;
border-radius: 50%;
animation: spin 0.7s linear infinite;
.dark & {
border-color: rgba(255, 255, 255, 0.18);
border-top-color: $accent-primary;
}
}
.scroll-bottom-button {
@@ -606,8 +606,8 @@ async function previewTextFile(path: string, fileName: string): Promise<void> {
align-items: center;
gap: 8px;
padding: 8px 12px;
background: rgba(0, 0, 0, 0.85);
color: #fff;
background: rgba(var(--bg-card-rgb), 0.92);
color: var(--text-primary);
font-size: 12px;
.att-name {
@@ -1698,20 +1698,12 @@ onBeforeUnmount(() => {
cursor: pointer;
border-radius: $radius-sm;
padding: 0;
color: var(--text-faint);
transition: color 0.15s ease, background 0.15s ease;
&:hover {
color: $text-secondary;
background: rgba(0, 0, 0, 0.06);
}
.dark & {
color: #999999;
&:hover {
color: #cccccc;
background: rgba(255, 255, 255, 0.1);
}
background: rgba(var(--text-primary-rgb), 0.1);
}
}
@@ -1738,12 +1730,8 @@ onBeforeUnmount(() => {
.message-time {
font-size: 11px;
color: $text-muted;
color: var(--text-faint);
user-select: none;
.dark & {
color: #999999;
}
}
.tool-line {
@@ -1876,12 +1864,6 @@ onBeforeUnmount(() => {
gap: 10px;
padding: 12px 14px;
width: 100%;
.dark & {
background: #1f1f1f;
border-color: rgba(255, 255, 255, 0.14);
color: #f2f2f2;
}
}
.tool-change-card-header {
@@ -1952,22 +1934,11 @@ onBeforeUnmount(() => {
&:hover,
&.selected {
.tool-change-file-name {
color: $text-primary;
color: var(--accent-primary);
text-decoration: underline;
text-underline-offset: 3px;
}
}
.dark & {
color: #f2f2f2;
&:hover,
&.selected {
.tool-change-file-name {
color: #ffffff;
}
}
}
}
.tool-change-file-main {
@@ -986,10 +986,6 @@ defineExpose({
border: 1px solid $border-color;
border-radius: 11px;
padding: 8px 10px;
.dark & {
background: rgba(255, 255, 255, 0.08);
}
}
.approval-float-actions {
@@ -1078,10 +1074,6 @@ defineExpose({
border-radius: 11px;
background: rgba(var(--bg-card-rgb), 0.68);
color: $text-primary;
.dark & {
background: rgba(255, 255, 255, 0.08);
}
}
.queue-index {
@@ -1258,15 +1250,10 @@ defineExpose({
.history-loader-spinner {
width: 14px;
height: 14px;
border: 2px solid rgba(0, 0, 0, 0.16);
border: 2px solid rgba(var(--text-primary-rgb), 0.18);
border-top-color: $accent-primary;
border-radius: 50%;
animation: spin 0.7s linear infinite;
.dark & {
border-color: rgba(255, 255, 255, 0.18);
border-top-color: $accent-primary;
}
}
.history-archive-link-wrap {
@@ -1418,10 +1405,7 @@ defineExpose({
border-radius: $radius-md;
object-fit: cover;
flex-shrink: 0;
.dark & {
filter: brightness(1.18) contrast(1.08) saturate(1.08);
}
filter: brightness(1.18) contrast(1.08) saturate(1.08);
}
.thinking-status-copy {
@@ -1438,7 +1422,8 @@ defineExpose({
display: inline-flex;
align-items: center;
color: transparent;
background: linear-gradient(105deg, $text-secondary 0%, $text-secondary 39%, #ffffff 48%, #ffffff 52%, $text-secondary 61%, $text-secondary 100%);
// 扫光带用霓虹青,底色用正文灰——CYBER 的高光是青色而不是白色。
background: linear-gradient(105deg, $text-secondary 0%, $text-secondary 37%, var(--accent-primary) 47%, var(--accent-primary) 53%, $text-secondary 63%, $text-secondary 100%);
background-size: 300% 100%;
background-position: 0% 0;
-webkit-background-clip: text;
@@ -1451,15 +1436,7 @@ defineExpose({
contain: paint;
transform: translateZ(0);
will-change: background-position;
.dark & {
background: linear-gradient(105deg, #f0f0f0 0%, #f0f0f0 37%, #2f3540 47%, #2f3540 53%, #f0f0f0 63%, #f0f0f0 100%);
background-size: 300% 100%;
background-position: 0% 0;
-webkit-background-clip: text;
background-clip: text;
filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.16));
}
filter: drop-shadow(0 0 5px rgba(var(--accent-primary-rgb), 0.2));
}
.thinking-status-time {
@@ -1510,13 +1487,9 @@ defineExpose({
font-size: 11px;
color: $text-secondary;
padding: 3px 8px;
background: rgba(0, 0, 0, 0.03);
background: rgba(var(--text-primary-rgb), 0.06);
border-radius: $radius-sm;
.dark & {
background: rgba(255, 255, 255, 0.06);
}
&.compression-item {
color: $text-muted;
font-size: 10px;
@@ -209,7 +209,7 @@ function scrollToTarget(item: OutlineItem) {
}
.user-question {
background-color: $bg-secondary;
background-color: $bg-input;
color: $text-primary;
padding: 8px 12px;
border-radius: 8px;
@@ -217,10 +217,6 @@ function scrollToTarget(item: OutlineItem) {
align-items: flex-start;
gap: 6px;
.dark & {
background-color: $bg-input;
}
.q-label {
font-weight: 600;
flex-shrink: 0;
@@ -258,11 +254,7 @@ function scrollToTarget(item: OutlineItem) {
transition: background-color 0.15s ease;
&:hover {
background-color: rgba(0, 0, 0, 0.04);
.dark & {
background-color: rgba(255, 255, 255, 0.06);
}
background-color: rgba(var(--text-primary-rgb), 0.06);
}
.level-1 & {
@@ -189,12 +189,12 @@ onUnmounted(() => {
padding: 8px 10px;
border: none;
background: none;
border-radius: var(--radius-sm);
border-radius: $radius-sm;
cursor: pointer;
text-align: left;
text-decoration: none;
color: var(--text-secondary);
transition: all var(--transition-fast);
transition: all $transition-fast;
margin-bottom: 2px;
}
@@ -312,7 +312,7 @@ onUnmounted(() => {
color: var(--text-muted);
cursor: pointer;
border-radius: 3px;
transition: all var(--transition-fast);
transition: all $transition-fast;
}
.session-item-delete:hover {
@@ -535,10 +535,6 @@ defineExpose({
padding: var(--virtual-list-padding);
box-sizing: border-box;
background-color: $bg-card;
.dark & {
background-color: #333333;
}
}
.virtual-row {
@@ -143,7 +143,7 @@ function cancel() {
appearance: none;
border: 0;
font: inherit;
color: var(--text-color-3, #999999);
color: var(--text-faint);
background: transparent;
cursor: pointer;
transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
@@ -161,22 +161,22 @@ function cancel() {
}
.voice-dialogue-controls__toggle:hover {
color: var(--text-color-2, currentColor);
background: rgba(128, 128, 128, 0.12);
color: var(--text-secondary);
background: rgba(var(--text-muted-rgb), 0.12);
}
.voice-dialogue-controls__toggle:focus-visible {
outline: 2px solid var(--primary-color, #18a058);
outline: 2px solid var(--accent-primary);
outline-offset: 2px;
}
.voice-dialogue-controls__toggle.active {
color: var(--error-color, #d03050);
background: rgba(208, 48, 80, 0.12);
color: var(--error);
background: rgba(var(--error-rgb), 0.12);
}
.voice-dialogue-controls__toggle.active:hover {
background: rgba(208, 48, 80, 0.18);
background: rgba(var(--error-rgb), 0.18);
}
.voice-dialogue-controls__icon {
@@ -204,7 +204,7 @@ function cancel() {
}
.voice-dialogue-controls__cancel:hover {
color: var(--text-color-2, currentColor);
background: rgba(128, 128, 128, 0.12);
color: var(--text-secondary);
background: rgba(var(--text-muted-rgb), 0.12);
}
</style>
@@ -73,10 +73,10 @@ const recentEventTypes = computed(() => props.events.slice(-5).map(event => even
min-width: 12rem;
padding: 0.5rem 0.75rem;
color: var(--text-primary);
border: 1px solid rgba(var(--text-primary-rgb), 0.12);
border: 1px solid var(--border-light);
border-radius: 0.75rem;
background: var(--bg-card, var(--bg-input, #ffffff));
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.14);
background: var(--bg-card);
box-shadow: 0 12px 34px oklch(0 0 0 / 0.42);
}
.voice-transcript-overlay--floating {
@@ -90,12 +90,6 @@ const recentEventTypes = computed(() => props.events.slice(-5).map(event => even
box-sizing: border-box;
}
.dark .voice-transcript-overlay {
border-color: rgba(255, 255, 255, 0.14);
background: var(--bg-card, #333333);
box-shadow: 0 12px 34px rgba(0, 0, 0, 0.42);
}
.voice-transcript-overlay__status,
.voice-transcript-overlay__transcript,
.voice-transcript-overlay__error,
@@ -109,7 +103,7 @@ const recentEventTypes = computed(() => props.events.slice(-5).map(event => even
}
.voice-transcript-overlay__error {
color: var(--error-color, #d03050);
color: var(--error);
}
.voice-transcript-overlay__debug {
@@ -32,7 +32,7 @@ onMounted(() => {
editor = monaco.editor.create(editorContainer.value, {
value: filesStore.editingFile.content,
language: filesStore.editingFile.language,
theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs',
theme: 'vs-dark',
minimap: { enabled: false },
fontSize: 13,
lineNumbers: 'on',
@@ -763,7 +763,7 @@ function isImage(type: string): boolean {
border-radius: 18px;
padding: 14px 12px 9px;
position: relative;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.08);
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.32);
transition: border-color $transition-fast, box-shadow $transition-fast;
&:focus-within {
@@ -775,11 +775,6 @@ function isImage(type: string): boolean {
border-color: $accent-primary;
background-color: rgba(var(--accent-primary-rgb), 0.04);
}
.dark & {
background-color: $bg-card;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.32);
}
}
.resize-handle {
@@ -949,7 +949,7 @@ export default defineComponent({ components: { CreateRoomForm } })
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
&:hover {
color: #ffffff;
color: var(--text-on-accent);
background: $error;
border-color: $error;
}
@@ -1028,19 +1028,11 @@ onBeforeUnmount(() => {
border-radius: $radius-sm;
padding: 0;
transition: color 0.15s ease, background 0.15s ease;
color: var(--text-faint);
&:hover {
color: $text-secondary;
background: rgba(0, 0, 0, 0.06);
}
.dark & {
color: #999999;
&:hover {
color: #cccccc;
background: rgba(255, 255, 255, 0.1);
}
background: rgba(var(--text-primary-rgb), 0.1);
}
}
@@ -232,15 +232,10 @@ defineExpose({ scrollToBottom })
.history-loader-spinner {
width: 14px;
height: 14px;
border: 2px solid rgba(0, 0, 0, 0.16);
border: 2px solid rgba(var(--text-primary-rgb), 0.18);
border-top-color: $accent-primary;
border-radius: 50%;
animation: spin 0.7s linear infinite;
.dark & {
border-color: rgba(255, 255, 255, 0.18);
border-top-color: $accent-primary;
}
}
.history-limit-notice {
@@ -199,14 +199,14 @@ startLogin()
align-items: center;
gap: 12px;
padding: 12px 20px;
border: 1px solid var(--color-border-2, #e0e0e6);
border: 1px solid var(--border-color);
border-radius: 8px;
cursor: pointer;
transition: border-color 0.2s;
background: var(--color-fill-2, #fafafa);
background: var(--bg-card);
&:hover {
border-color: var(--arcoblue-6, #165dff);
border-color: var(--accent-primary);
}
}
@@ -201,14 +201,14 @@ startLogin()
align-items: center;
gap: 12px;
padding: 12px 20px;
border: 1px solid var(--color-border-2, #e0e0e6);
border: 1px solid var(--border-color);
border-radius: 8px;
cursor: pointer;
transition: border-color 0.2s;
background: var(--color-fill-2, #fafafa);
background: var(--bg-card);
&:hover {
border-color: var(--arcoblue-6, #165dff);
border-color: var(--accent-primary);
}
}
@@ -201,14 +201,14 @@ startLogin()
align-items: center;
gap: 12px;
padding: 12px 20px;
border: 1px solid var(--color-border-2, #e0e0e6);
border: 1px solid var(--border-color);
border-radius: 8px;
cursor: pointer;
transition: border-color 0.2s;
background: var(--color-fill-2, #fafafa);
background: var(--bg-card);
&:hover {
border-color: var(--arcoblue-6, #165dff);
border-color: var(--accent-primary);
}
}
@@ -150,12 +150,12 @@ function saveExclude(value: string[]) {
margin: 0 0 6px;
font-size: 15px;
font-weight: 600;
color: var(--text-color);
color: var(--text-primary);
}
.section-hint {
margin: 0 0 12px;
color: var(--text-color-secondary);
color: var(--text-secondary);
font-size: 13px;
}
@@ -520,7 +520,7 @@ async function handleSave() {
.form-section + .form-section {
padding-top: 12px;
border-top: 1px solid var(--border-color, rgba(0, 0, 0, 0.08));
border-top: 1px solid var(--border-color);
}
.section-heading {
@@ -545,7 +545,7 @@ async function handleSave() {
.inline-error {
display: grid;
gap: 6px;
color: var(--danger-6, #d03050);
color: var(--error);
font-size: 12px;
line-height: 1.4;
}
@@ -557,13 +557,13 @@ async function handleSave() {
overflow: auto;
white-space: pre-wrap;
color: inherit;
background: rgba(208, 48, 80, 0.06);
background: rgba(var(--error-rgb), 0.06);
border-radius: 6px;
}
.link-button {
padding: 0;
color: var(--primary-6, #18a058);
color: var(--accent-primary);
background: transparent;
border: 0;
cursor: pointer;
+4 -4
View File
@@ -449,21 +449,21 @@ $neon-hv: var(--accent-hover);
box-shadow: 0 0 8px rgba(var(--accent-primary-rgb), 0.5);
}
// 下拉 / 弹层的浮层背景
// 下拉 / 弹层的浮层背景。浮层要浮在内容之上,用最亮的一层底。
.arco-trigger-popup,
.arco-select-popup,
.arco-picker-dropdown,
.arco-dropdown,
.arco-modal,
.arco-drawer {
background-color: var(--surface-2);
background-color: var(--bg-card);
border: 1px solid var(--border-color);
box-shadow: var(--shadow, 0 18px 48px oklch(0 0 0 / 0.55));
box-shadow: 0 18px 48px oklch(0 0 0 / 0.55);
}
// 表格:去掉亮色分隔线的突兀感,表头沉下去
.arco-table-th {
background-color: var(--surface-2);
background-color: var(--bg-secondary);
color: $text-muted;
border-color: $border-color;
font-family: $font-code;
@@ -86,6 +86,7 @@ $accent-muted: var(--accent-muted);
$text-primary: var(--text-primary);
$text-secondary: var(--text-secondary);
$text-muted: var(--text-muted);
$text-faint: var(--text-faint);
// Status
$success: var(--success);
@@ -402,7 +402,7 @@ function drawNode(node: ProjectedNode, activeId: string, activeNeighbors: Set<st
if (node.pinned || active) {
ctx.shadowBlur = 0
ctx.strokeStyle = active ? 'rgba(255,255,255,0.9)' : 'rgba(255, 190, 90, 0.85)'
ctx.strokeStyle = active ? 'rgba(235, 255, 252, 0.92)' : 'rgba(45, 212, 191, 0.7)'
ctx.lineWidth = active ? 2 : 1.4
ctx.beginPath()
ctx.arc(node.sx, node.sy, node.size + 5, 0, Math.PI * 2)
@@ -326,7 +326,7 @@ onMounted(() => {
margin-top: 10px;
a {
color: var(--primary-color);
color: var(--accent-primary);
font-size: 12px;
text-decoration: none;
@@ -2399,7 +2399,7 @@ function nodeColor(node: { data: WorkflowAgentNodeData }) {
color: var(--text-muted);
cursor: pointer;
border-radius: 3px;
transition: all var(--transition-fast);
transition: all $transition-fast;
&:hover {
color: var(--error);