Skip to content

[Bug] Dashboard theme does not penetrate the OpenCode embed (Shadow DOM); workbench renders dark on light themes #589

@brendandebeasi

Description

@brendandebeasi

Summary

On the vanilla (light) theme, the workbench task pane shows dark-gray boxes and buttons against a light surrounding surface — the OpenCode-embedded chat composer inside each WorkerColumn keeps OpenCode's bundled dark styling regardless of the dashboard theme. This isn't a vanilla-specific regression; it's a structural issue affecting every Spacebot theme. Vanilla just makes it visible because the contrast is jarring.

Root cause

The "comment box" in the workbench is OpenCode's prompt input, embedded via OpenCodeEmbed.tsx. OpenCode is mounted inside a Shadow DOM (interface/src/components/OpenCodeEmbed.tsx:254):

const shadow = host.shadowRoot ?? host.attachShadow({mode: "open"});

Shadow DOM does not inherit selector-based styles or CSS custom properties from the document tree. That means:

  1. Theme classes don't reach the embed. useTheme.ts:77 adds .vanilla-theme (or similar) to document.documentElement. The .vanilla-theme { … } selector in @spacedrive/tokens/.../themes/light.css cannot match anything inside the shadow root.
  2. CSS variables don't propagate. The Spacebot tokens (--color-app-box, --color-app-line, --color-ink, …) are declared on :root / .vanilla-theme of the document, not the shadow.
  3. The shadow's stylesheet is OpenCode's bundle, untouched. Lines 260-262 inject only the OpenCode-shipped CSS plus a small overrides block (lines 266-282).
  4. The overrides block tries to use Spacebot tokens but they're undefined inside the shadow. Lines 277-278:
    [data-component="prompt-input"] {
        background: color-mix(in srgb, var(--color-app-box) 70%, transparent) !important;
        border: 1px solid var(--color-app-line) !important;
    }
    var(--color-app-box) and var(--color-app-line) resolve to their initial values inside the shadow root, so the override either falls through or matches OpenCode's defaults rather than Spacebot's theme.

Repro

  1. Switch to the vanilla theme
  2. Open the Workbench with at least one running task
  3. Observe dark-gray prompt input + button backgrounds inside each WorkerColumn against the light surrounding panel

Same effect (less visually obvious) on every dark Spacebot theme — OpenCode's dark just happens to look "close enough" to most of them.

Proposed fix

Three layers, smallest first:

  1. Forward CSS variables into the shadow. In OpenCodeEmbed.tsx, after attachShadow, read the resolved values of Spacebot's tokens from getComputedStyle(document.documentElement) and inject them as :host { --color-app: …; --color-app-box: …; --color-app-line: …; --color-ink: …; … } into the existing overrides style. Re-run when the theme changes (subscribe to useTheme).
  2. Tell OpenCode which mode to use. If OpenCode's embed exposes a theme prop / API, pass light vs dark derived from the current Spacebot theme (vanilla → light; everything else → dark today). If not, file an upstream feature request — that's the only proper fix for the inner button/textarea colors which are styled by OpenCode itself, not Spacebot's overrides.
  3. Stopgap: widen the overrides block. Add explicit selectors for [data-component="prompt-input"] textarea, [data-component="prompt-input"] button, etc., styled from the forwarded variables in step 1.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions