Files
hermes-ui/docs/chat-chain-changes/2026-10-19-cyber-theme-chat-chain.md
T
toor 3debe903f7 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.
2026-10-19 14:56:23 +08:00

3.3 KiB

date, pr, feature, impact
date pr feature impact
2026-10-19 pending CYBER theme - chat chain restyled onto the single dark token set 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.