Skip to content

feat(web): add dimmed background scenes behind a tinted-glass interface - #12897

Draft
saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:feat/theme-backgrounds
Draft

saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:feat/theme-backgrounds

Conversation

@saphid

@saphid saphid commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Problem

T3 Code's themes set colors, but the workspace is always a flat opaque surface. Bambooed-style
apps show that a calm scene behind a translucent interface makes long sessions feel noticeably
less sterile, and our glass utilities (surface-glass, the glass-opacity setting) already exist
but have nothing scenic behind them to show through.

Change

Every built-in theme ships a matching scenic backdrop (apps/web/public/backgrounds/, one webp
per theme, generated with image generation and compressed to 23-125 KB each). When a scene is
active, a fixed dimmed image paints under every surface, and the main canvas fills re-derive
from the theme's solid colors at partial alpha, so the interface reads as tinted glass over the
scene:

  • A themeBackground client setting (auto / none / a built-in theme id) lands in
    packages/contracts. Theme scene follows the active theme, a picked scene sticks across
    theme changes, None turns the backdrop off.
  • The scene layer paints on body::before under all content; large surfaces get no
    backdrop-filter (one blurred layer that big repaints on every streaming frame). The scenes
    are generated softly defocused instead.
  • Nested bg-background containers stop re-painting while a scene is active, so the glass stays
    a single layer instead of stacking into opacity.
  • Terminal fills stay solid; dialogs and popovers keep their existing glass treatment.
  • Picker lives in Settings → Appearance → Background scene, searchable as "background scene".
  • Dark mode keeps the scene subtle (higher surface opacity + stronger dim) so text contrast on
    the dark palettes is preserved.

Mobile is untouched: it renders its own theme system and palette, and the backdrop piggybacks on
the web theme pipeline. Desktop picks this up automatically since it wraps the web client.

Evidence

Before/after captures of the running client (same workspace, same threads; "before" is the
candidate with the scene set to None, which renders the identical base path):

After (Ocean theme, scene visible through the interface):

After (T3 Chat theme):

Before (scene off):

Settings entry point:

Gap: the screenshot files are captured and ready (/tmp/t3-pr-evidence/) but the file-drop
upload credential was not available in this session, so the images are not yet attached. They
will be uploaded and linked here before the draft leaves draft state.

Verification

  • vp test run apps/web/src/themeBackground.test.ts packages/contracts/src/settings.test.ts apps/web/src/components/settings/settingsSearch.test.ts apps/web/src/hooks/useTheme.test.ts — 210 passed.
  • pnpm --filter @t3tools/contracts typecheck, pnpm --filter @t3tools/web typecheck — clean.
  • vp lint on the touched files — no new warnings (remaining ones pre-date this change).
  • Integrated pass in a real client (vp run dev in an isolated worktree, paired browser,
    real workspace data): scene follows theme switches and appearance flips, picker updates live,
    None restores the base rendering, browser chrome theme sync stays correct with the body fill
    cleared.

Model and harness: GLM (enablers/xlarge) via T3 Code / OpenCode, with Codex CLI image generation
for the five scenes and Codex visual QA of the captures.

Every built-in theme ships a matching scenic backdrop that paints behind
the app. Main canvas fills re-derive from the theme's solid colors at
partial alpha so the interface reads as tinted glass over the scene, and
nested bg-background containers stop re-painting so the glass stays one
layer. Pick the scene in Settings > Appearance: Theme scene follows the
active theme, a specific scene sticks across theme changes, None turns
it off. Dark mode keeps the scene subtle to preserve text contrast.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 21, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant