Add dark mode support for content frame - #2652
Conversation
…d tokens Define 14 frame-* CSS custom properties in :root with prefers-color-scheme dark overrides. Add matching Tailwind color tokens (frame, frame-text, frame-border, frame-surface, etc.). Enable Electron nativeTheme.themeSource = 'system' so the renderer respects OS dark mode. Apply bg-frame and text-frame-text to the content frame in app.tsx. Add dark mode override block in index.css targeting WP component classes (inputs, buttons, tabs, modals, popovers) using :is() for scoped element cascade. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded text-black with text-frame-text in secondary and link active states. Replace bg-gray-100 with bg-frame-surface in outlined hover/active states. Replace hover:bg-white with hover:bg-frame-surface in icon variant. This eliminates the root cause of most !important overrides in consumer components. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The fullscreen modal renders outside both [data-testid='site-content'] and .components-modal__frame, so dark mode overrides couldn't reach its children. Add data-fullscreen-modal attribute as a CSS hook. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… tokens Replace bg-white, bg-gray-*, text-gray-*, text-black, border-gray-*, and hardcoded hex colors with frame-* Tailwind tokens across all content tab components, assistant chat UI, welcome prompts, and shared components. Key changes: assistant tab bg-gray-50 -> bg-frame-surface, chat input bg-frame (solid, since opacity modifiers fail on hex custom properties), chat message borders, skeleton loaders, error states, and SVG fills. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace text-gray-900, bg-gray-50, bg-[#FAFAFA], border-gray-200, fill='#949494', and other hardcoded colors with frame-* tokens across all add-site components: options, create-site form, blueprints, blueprint details/deeplinks, import backup, pull remote, and stepper. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace text-gray-*, text-[#3C434A], bg-white, border-a8c-gray-0, and other hardcoded colors with frame-* tokens in sync module (connected sites, dialog, modal selector, environment badge, site name box), preview site rows/headers, onboarding, and What's New modal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…f filter invert The invert(1) filter turned the blue hover color (#3858E9) into yellow (#C7A716). Replace with a white-fill SVG so hover stays blue in both color schemes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… accent Rename --color-frame-link/--color-frame-link-hover CSS custom properties to --color-frame-theme/--color-frame-theme-hover to better reflect their role as the app-wide accent color, not just link styling. Also sets --wp-admin-theme-color to var(--color-frame-theme) so WordPress component hover/focus styles (box-shadow, background) adapt to dark mode instead of using hardcoded #3858e9. Adds dark mode override for the assistant tab hover icon SVG data URI (#6b8aff instead of light-mode #3858E9). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all text-a8c-blue-50, bg-a8c-blue-50, fill-a8c-blue-50, border-a8c-blue-50, shadow-a8c-blue-50, ring-a8c-blue-50, and outline-a8c-blue-50 class references with their frame-theme equivalents across ~30 component and module files. These classes now resolve through CSS custom properties, enabling automatic dark mode color adaptation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convert SVG components and inline styles from hardcoded #3858E9: - wordpress-short-logo, blueprint-icon: use currentColor + style prop - sync-tab-image, screenshot-demo-site: use var(--color-frame-theme) - wordpress-logo-circle: default prop to var(--color-frame-theme) - options.tsx: Icon fill props to var(--color-frame-theme) - onboarding gradient: from-[var(--color-frame-theme)] - about-menu.html: inline CSS vars with dark mode media query SVG asset files in whats-new/assets/ left unchanged (loaded as <img>). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Unify link/copy-button hover to frame-theme (not frame-theme-hover) so all interactive text uses the same blue on hover - Add fill-frame-theme on hover for secondary button SVG icons so shortcut button icons (Site Editor, Styles, etc.) turn blue on hover - Fix icon-variant hover: use bg-white/10 instead of bg-frame-surface with bg-opacity-10, which didn't compose (CSS vars ignore bg-opacity) and showed a solid light grey square in the dark titlebar chrome Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set --wp-components-color-foreground/background so Emotion-styled WP components (ProgressBar, etc.) adapt to dark mode. Override the ProgressBar indicator to use frame-theme blue instead of the default foreground color-mix. Update TwoColorProgressBar track default to frame-text-secondary for dark mode visibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --color-frame-running token (green-50 light, green-20 dark) so the action button adapts to both modes. Replace hardcoded hex greens in the sidebar dot with a8c-green-20 palette classes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Hey @shaunandrews ! Thanks for working on that - it looks like an interesting addition. I think it would make sense to do the following before we pass it for review:
You could also consider adding it to the What's New dialog. |
Adds an Appearance picker to Preferences with three options that control Electron's nativeTheme.themeSource, so existing CSS dark mode rules work as-is. Preference persists to appdata and restores on startup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace dropdown with three illustrated cards (System/Light/Dark) that save immediately on click. Update SVG assets and reduce Settings modal max-height override so content isn't clipped. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded a8c-gray classes with frame-text and frame-text-secondary tokens so the error screen respects the user's color scheme preference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e assertion Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts: # apps/studio/src/components/link-button.tsx # apps/studio/src/modules/add-site/components/blueprint-deeplink.tsx # apps/studio/src/modules/sync/components/sync-sites-modal-selector.tsx
📊 Performance Test ResultsComparing f723f91 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
|
@shaunandrews, thanks for adding settings UI. Some notes regarding UX:
|
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…/studio into add-dark-mode-support
# Conflicts: # apps/studio/e2e/page-objects/user-settings-modal.ts # apps/studio/src/components/content-tab-overview.tsx # apps/studio/src/modules/sync/components/sync-connected-sites.tsx # apps/studio/src/modules/sync/components/sync-sites-modal-selector.tsx # apps/studio/src/modules/user-settings/components/preferences-tab.tsx
There was a problem hiding this comment.
@shaunandrews, thanks for creating this PR. I tested the app holistically and only found a few places where we could improve the colors for accessibility reasons. There were some conflicts, and I pushed a commit to fix them and pull the latest changes from trunk 1d084ed
I suggest collaborating next week to bring this PR over the finish line. Thank you!
Here are the components that I identified as needing improvement:
Push warning
Site title to connect sites
AI animated icon and maybe arrows links
Some links are difficult for me to identify; they are clickable.
File icons on selective push
Password input in site settings
I think it's too bright-white.
Here is a video with all my testing:
light-dark-mode-web.mp4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add allowDefaultProject for tailwind.config.js in eslint config and fix import order. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Override Emotion-generated styles for modals, input controls, primary buttons, link button hover, notices, and the span text cascade to properly support dark mode without breaking light mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace text-a8c-gray-50/70/700/30, fill-a8c-gray-*, border-gray-*, and bg-gray-* with semantic frame-text-secondary, frame-border, and frame-surface tokens across all content frame components. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use frame-surface for hover, white text for selected rows, and white badge on selected. Environment badges use fixed colors that work on both light and dark backgrounds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use frame-border, frame-surface, and frame-text tokens. Replace hardcoded disabled grays with opacity approach for consistency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add fill-frame-text to tree view file/folder icons. Add select-minimal class to sync dialog select to preserve borderless style in dark mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…/studio into add-dark-mode-support # Conflicts: # apps/studio/src/components/ai-settings-modal.tsx
|
Thanks for the review! I've got through and fixed a bunch! I wasn't able to change the Rive animation for the Assistant tab input, but I don't think that's a blocker. (I honestly kind of hate it, and would rather just remove it than generate a dark-mode variant.) WP component overrides (
|
|
I'll make one last review and push some small fixes if I find anything. |
There was a problem hiding this comment.
Thanks for adjusting the PR. I just pushed a fix for notices. f723f91
| Light | Dark |
|---|---|
![]() |
![]() |
I also confirm that the rest of the improvements were fixed. The only exception would the Rive AI animation.
Passowrd input
Files icons
Learn more and arrow icons
Site selection
|
doh, i missed the notice! thanks for the fix |





Summary
prefers-color-scheme: dark) for the content frame area while keeping the sidebar chrome permanently dark--color-frame-*) with dark mode overrides, mapped to Tailwind tokens (frame-*)nativeTheme.themeSource = 'system'so the renderer respects OS preference:is()for WP component classes (inputs, buttons, tabs, modals, popovers, menus)text-black/bg-whitewithframe-*tokenstext-gray-*,bg-white,border-gray-*, hex values) to semanticframe-*tokensTest plan
#2F2F2F