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
@@ -0,0 +1,61 @@
---
date: 2026-10-19
pr: pending
feature: CYBER theme - chat chain restyled onto the single dark token set
impact: Rendering-layer only. Every chat-chain style block is moved onto the CYBER dark tokens, all `.dark` override branches are deleted because dark is now the only theme, and two latent bugs are fixed as a side effect (Monaco loaded the light `vs` theme; four Arco RGB-triplet variables were used as colors and silently fell back). No chat store logic, no `/chat-run` payload, and no message rendering path is touched.
---
# CYBER theme — chat chain
The chat chain was restyled onto the token set in `packages/client/src/styles/variables.scss`.
The theme is a single dark palette: `useTheme()` pins `isDark` to `true` and the brightness
switcher was removed, so any `.dark` selector now always matches and any non-`.dark` branch
is unreachable.
## Why chat-chain files changed
Fifteen files under the chat chain were caught by the restyle. None of the changes touch logic.
### Deleting `.dark` branches
Because `.dark` is unconditionally present, every `.dark &` block was an unconditional
override sitting on top of a token-based base rule — and each one carried a hardcoded gray
from the previous theme. The value was merged down into the base rule and the wrapper
deleted. Fourteen blocks across ten files were affected, including three that pinned
`background-color: #333333` (a neutral gray that fought the blue-black CYBER palette) and
one that set the thinking-shimmer sweep band to white.
### `#999999` / `#cccccc` / `#f2f2f2` / `#1f1f1f` / `#2a2a2a`
Fifteen hardcoded legacy grays in `MessageItem.vue`, `MessageList.vue`, `ChatInput.vue`,
`GroupMessageItem.vue` and `VirtualMessageList.vue` were rewritten to `--text-faint`,
`--text-secondary`, `--bg-card` and `rgba(var(--text-primary-rgb), …)`.
### Latent bugs fixed
- **`files/FileEditor.vue`** picked the Monaco theme with
`document.documentElement.classList.contains('dark')`. The `dark` class is bound on
`.app-root` in `App.vue`, not on `<html>`, so the check was always false and Monaco
always loaded the **light** `vs` theme inside the dark editor surface. Pinned to
`vs-dark`.
- **Arco RGB triplets used as colors.** `CodexLoginModal.vue`, `CopilotLoginModal.vue` and
`NousLoginModal.vue` wrote `border-color: var(--arcoblue-6, #165dff)` and
`VoiceApiFormModal.vue` wrote `color: var(--primary-6, #18a058)`. Those variables hold
bare triplets (`22,93,255`), not colors, so each declaration was invalid and silently
discarded — the hover border and link color fell back to the stock Arco blue/green rather
than the CYBER accent. Rewritten to `--accent-primary`.
- **`JourneyView.vue`** drew the pinned-node ring in `rgba(255, 190, 90, 0.85)`, an amber
left over from the previous palette. Now uses the cyan edge palette like every other
stroke in that canvas.
## Verification
`grep -rn "\.dark" packages/client/src` returns no style-block matches. A token-reference
scan comparing every `var(--x)` against the definitions in `variables.scss`, `global.scss`
and `arco.css` reports only locally-defined per-component variables.
## Behavior impact
Rendering-layer only. No chat store logic, no `/chat-run` payload, and no message rendering
path was touched. The voice overlay, transcript controls, and the thinking indicator keep
their existing markup and event wiring; only their colors and shadows changed.