Skip to content

Sync Studio light-mode support into the admin-app - #154

Merged
jackgranatowski merged 3 commits into
mainfrom
claude/sync-studio-light-mode
Jul 3, 2026
Merged

jackgranatowski merged 3 commits into
mainfrom
claude/sync-studio-light-mode

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to the closed #148, which depended on the framework PR (#500) before it was split for reviewability. That split is now fully merged into codeslash-dev/SLASHED's main across #506, #507, #508, and a final #510 (landing a stacked-merge gap where #507/#508 had merged into intermediate feature branches instead of main — see that PR's description for details).

What this PR does

  • Vendors the complete, now-merged light-mode rollout from the framework: theme system (theme.svelte.ts), the Sun/Moon toggle in the header, and light-mode Tailwind pairings across the whole Studio shell and every domain panel.
  • Rebuilds assets/admin-app/app.js + app.css.
  • Pins AppOverlay.svelte's root to the dark class (plugin-specific, not vendored). It reuses SidebarNav/DomainPanel/CommandPalette from the vendored core, which now default to light unless an ancestor opts into dark via Tailwind's class-based dark: variant. The frontend overlay's own shell markup is still hardcoded dark, so this keeps the embedded components visually consistent with it instead of mismatching (light nav inside a dark shell). A full light-mode pass for the overlay itself is out of scope here — same as the original feat: add light/dark theme toggle to studio chrome #148.

Verification

  • npx svelte-check — 0 errors (the 1 pre-existing plugin-main.ts error is unrelated, confirmed present on a clean main checkout before this change)
  • npm run build:admin-app — builds cleanly
  • npm test — 142/142 passing
  • npm run check — admin-app sync drift check passes (the variables-hints.json staleness it also reports is pre-existing, unrelated to this change)

Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added a light/dark theme toggle for the app, with saved preference and system-theme support.
    • Improved initial theming so the correct mode appears immediately on load.
  • Style
    • Refined visual styling across the interface for better contrast and consistency in dark mode.
    • Updated panels, inputs, buttons, and previews to match the active theme more reliably.

Vendors the completed SLASHED framework light-mode rollout
(codeslash-dev/SLASHED PRs #506, #507, #508, #510 — theme system,
Sun/Moon toggle, and light-mode Tailwind pairings across the whole
Studio chrome and every panel) and rebuilds the admin SPA bundle.

Also pins AppOverlay.svelte's root to the `dark` class: it reuses
SidebarNav/DomainPanel/CommandPalette from the vendored core, which now
default to light unless an ancestor opts into dark via Tailwind's
class-based dark variant. The frontend overlay's own shell markup is
plugin-specific and still hardcoded dark, so forcing `dark` on its root
keeps the embedded components visually consistent with it instead of
mismatching (light nav inside a dark shell).
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jackgranatowski, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 58 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 07423d3c-452d-43e2-a966-3f18549d0dd2

📥 Commits

Reviewing files that changed from the base of the PR and between 67cb731 and 9d20418.

📒 Files selected for processing (6)
  • SLASHED-for-WP/admin-app/src/components/inputs/SliderRow.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/CheatsheetPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/HomePanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/ThemesPanel.svelte
  • SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts
  • SLASHED-for-WP/admin-app/src/plugin-main.ts
📝 Walkthrough

Walkthrough

This PR adds a persisted light/dark theme controller (theme.svelte.ts) bound at app mount and forced to dark in the overlay context, then propagates theme-aware Tailwind classes across the admin app shell, input components, and all configuration panels. It also updates vendored-manifest provenance metadata and stylelint ignore rules.

Changes

Dark/light theme support

Layer / File(s) Summary
Theme controller and bootstrap wiring
SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts, SLASHED-for-WP/admin-app/src/main.ts, SLASHED-for-WP/admin-app/src/plugin-main.ts, SLASHED-for-WP/admin-app/src/app.css, .stylelintrc.json
New Theme type, persisted/system-derived themeState, bindThemeRoot/setTheme/toggleTheme exports; wired into main mount and overlay mount (forced dark); Tailwind dark variant added; app.css excluded from stylelint.
App shell and header theming
App.svelte, AppOverlay.svelte, StudioHeader.svelte, SidebarNav.svelte, StatusBar.svelte, PreviewPanel.svelte, DomainPanel.svelte, CommandPalette.svelte
Light/dark Tailwind classes applied throughout shell components; new theme toggle button (Sun/Moon icons) added to header.
Input control theming
ClampField.svelte, ColorInput.svelte, OklchColorDesk.svelte, PowerKnobRow.svelte, RangeWithNumber.svelte, SliderRow.svelte, TokenRow.svelte
Theme-aware background/border/text classes and derived optionBg values applied to inputs, sliders, and token rows.
Token listing, home, export, and themes panel theming
AllTokensTab.svelte, GenericTokenPanel.svelte, HomePanel.svelte, ExportPanel.svelte, ThemesPanel.svelte, CheatsheetPanel.svelte
Dark-mode-aware classes for search inputs, lists, badges, and copy/save/apply controls.
Borders, Colors, Effects, Shadows, Spacing panel theming
BordersPanel.svelte, ColorsPanel.svelte, EffectsPanel.svelte, ShadowsPanel.svelte, SpacingPanel.svelte
Dividers, previews, and controls restyled with paired light/dark Tailwind classes.
Layout, Macros, Misc, Motion, Typography, WCAG panel theming
LayoutPanel.svelte, MacrosPanel.svelte, MiscPanel.svelte, MotionPanel.svelte, TypographyPanel.svelte, WcagPanel.svelte
Derived optionBg for select elements and broad dark-mode Tailwind class updates across all controls and previews.
Vendored manifest provenance update
.vendored-manifest.json
_info.source/syncedAt and per-file source fields switched from GitHub references to local paths.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MainTs as main.ts
  participant PluginMainTs as plugin-main.ts
  participant ThemeModule as theme.svelte.ts
  participant DomRoot as App root element

  MainTs->>ThemeModule: bindThemeRoot(target)
  ThemeModule->>ThemeModule: readStored() / systemTheme()
  ThemeModule->>DomRoot: applyToRoot() toggles "dark" class
  PluginMainTs->>ThemeModule: themeState.value = "dark"
  ThemeModule->>DomRoot: applyToRoot() forces dark for overlay
Loading

Possibly related PRs

Suggested labels: codex

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: syncing Studio light-mode support into the admin-app.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/sync-studio-light-mode

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Sync Studio light-mode support into the admin-app

✨ Enhancement ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Vendor Studio chrome light/dark theming and header Sun/Moon toggle into admin-app.
• Update Tailwind classes across shell/components/panels for light-mode parity via dark: variants.
• Rebuild admin-app bundle artifacts and force AppOverlay to remain dark for visual consistency.
Diagram

graph TD
  A["admin-app/src/main.ts"] --> B["bindThemeRoot(target)"] --> C(("themeState")) --> D["Root toggles .dark"] --> G["Components use dark: classes"]
  E["StudioHeader"] --> F["toggleTheme()"] --> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Centralize chrome colors via CSS variables
  • ➕ Reduces duplicated light/dark class pairs across many components
  • ➕ Makes future theme tweaks lower-churn
  • ➖ Bigger refactor and diverges from upstream (harder to keep vendored code in sync)
  • ➖ Requires a design-token-like layer for chrome colors
2. Shared helper for `` backgrounds
  • ➕ Removes repeated optionBg = $derived(...) logic across panels
  • ➕ Keeps select option theming behavior consistent
  • ➖ Introduces a new abstraction that may not exist upstream (potential sync drift)
  • ➖ Still needs inline styles due to browser limitations
3. Prefer system theme only (remove manual toggle)
  • ➕ Less state/persistence logic and fewer UI controls
  • ➖ Removes explicit user control; conflicts with upstream UX expectations

Recommendation: Keep the PR’s approach: it mirrors the upstream SLASHED configurator (minimizing future vendoring drift) and binds the theme root before mount to prevent a wrong-themed first paint. If a follow-up is desired, a small shared helper for select `` background styling is the most pragmatic deduplication without changing the architecture.

Files changed (38) +935 / -805

Enhancement (34) +850 / -729
App.svelteMake Studio shell light by default with dark overrides +7/-7

Make Studio shell light by default with dark overrides

• Updates root layout backgrounds/text to support light mode and 'dark:' variants. Adjusts mobile fold toggle and domain panel chrome to match new theming.

SLASHED-for-WP/admin-app/src/App.svelte

AppOverlay.svelteForce overlay container into dark mode +1/-1

Force overlay container into dark mode

• Adds the 'dark' class to the overlay root to keep vendored components visually consistent inside the overlay’s dark-only shell.

SLASHED-for-WP/admin-app/src/AppOverlay.svelte

CommandPalette.svelteLight/dark styling parity for command palette +16/-16

Light/dark styling parity for command palette

• Converts palette container, borders, placeholder text, and hover states to light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/CommandPalette.svelte

DomainPanel.svelteLight/dark styling parity for domain panel tab bar +6/-6

Light/dark styling parity for domain panel tab bar

• Updates tab bar backgrounds/borders and selected/hover states to support light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/DomainPanel.svelte

ClampField.svelteTheme-aware select option backgrounds + light-mode styling +21/-15

Theme-aware select option backgrounds + light-mode styling

• Adds light/dark class pairings for the clamp card and inputs. Derives '<option>' background inline from 'themeState' to avoid unreliable 'dark:' styling on options.

SLASHED-for-WP/admin-app/src/components/inputs/ClampField.svelte

ColorInput.svelteLight-mode styling for color input row +5/-5

Light-mode styling for color input row

• Updates swatch border, text colors, hover states, and reset affordance for light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/inputs/ColorInput.svelte

OklchColorDesk.svelteLight-mode styling for OKLCH editor card +13/-13

Light-mode styling for OKLCH editor card

• Updates card background/borders and text colors to be light by default while preserving dark mode via 'dark:' variants.

SLASHED-for-WP/admin-app/src/components/inputs/OklchColorDesk.svelte

PowerKnobRow.svelteLight/dark Tailwind pairing for power knob row +4/-4

Light/dark Tailwind pairing for power knob row

• Adjusts power knob row styling to render correctly in light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/inputs/PowerKnobRow.svelte

RangeWithNumber.svelteLight/dark Tailwind pairing for range+number input +3/-3

Light/dark Tailwind pairing for range+number input

• Updates input and track styling to support light mode defaults with dark overrides.

SLASHED-for-WP/admin-app/src/components/inputs/RangeWithNumber.svelte

SliderRow.svelteLight-mode styling for slider rows and raw input mode +7/-7

Light-mode styling for slider rows and raw input mode

• Adjusts label colors, reset affordances, raw input styling, and help text for light mode readability with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/inputs/SliderRow.svelte

TokenRow.svelteLight-mode styling for token list rows +8/-8

Light-mode styling for token list rows

• Updates hover backgrounds, swatch borders, token/description text colors, and reset button styling for light mode with dark overrides.

SLASHED-for-WP/admin-app/src/components/inputs/TokenRow.svelte

AllTokensTab.svelteLight/dark styling parity for all-tokens tab +11/-11

Light/dark styling parity for all-tokens tab

• Converts panel chrome and text colors to light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/AllTokensTab.svelte

BordersPanel.svelteLight-mode styling for borders panel and previews +25/-25

Light-mode styling for borders panel and previews

• Updates section dividers, preview cards, and segmented controls to be light by default with dark overrides.

SLASHED-for-WP/admin-app/src/components/panels/BordersPanel.svelte

CheatsheetPanel.svelteLight-mode styling for cheatsheet and kind badges +31/-31

Light-mode styling for cheatsheet and kind badges

• Adds light+dark variants for kind color classes. Updates search UI, tab switcher, and result rows to support light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/CheatsheetPanel.svelte

ColorsPanel.svelteLight-mode styling for semantic color previews +83/-83

Light-mode styling for semantic color previews

• Updates preview borders/text and section separators for light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/ColorsPanel.svelte

EffectsPanel.svelteLight/dark styling parity for effects panel +26/-26

Light/dark styling parity for effects panel

• Adjusts panel backgrounds/borders/text to support light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/EffectsPanel.svelte

ExportPanel.svelteLight/dark styling parity for export panel +14/-14

Light/dark styling parity for export panel

• Updates export panel chrome styling to support light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/ExportPanel.svelte

GenericTokenPanel.svelteLight/dark styling parity for generic token panel +4/-4

Light/dark styling parity for generic token panel

• Converts generic token panel chrome to light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/GenericTokenPanel.svelte

HomePanel.svelteLight-mode styling for home panel and saved themes cards +22/-22

Light-mode styling for home panel and saved themes cards

• Updates landing panel typography, hover states, and saved-theme cards to be light by default with dark overrides.

SLASHED-for-WP/admin-app/src/components/panels/HomePanel.svelte

LayoutPanel.svelteTheme-aware select option backgrounds + light-mode styling +62/-57

Theme-aware select option backgrounds + light-mode styling

• Adds 'themeState'-derived '<option>' background inline styling and updates previews/dividers to support light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/LayoutPanel.svelte

MacrosPanel.svelteLight/dark styling parity for macros panel +41/-41

Light/dark styling parity for macros panel

• Updates macros panel chrome and text colors to support light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/MacrosPanel.svelte

MiscPanel.svelteLight-mode styling for misc panel and previews +73/-73

Light-mode styling for misc panel and previews

• Updates preview cards, segmented controls, helper text, and separators for light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/MiscPanel.svelte

MotionPanel.svelteTheme-aware select option backgrounds + light-mode styling +43/-38

Theme-aware select option backgrounds + light-mode styling

• Adds 'themeState'-derived '<option>' background inline styling and updates controls/previews for light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/MotionPanel.svelte

ShadowsPanel.svelteLight/dark styling parity for shadows panel +18/-18

Light/dark styling parity for shadows panel

• Updates shadows panel chrome and preview styling to support light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/ShadowsPanel.svelte

SpacingPanel.svelteLight/dark styling parity for spacing panel +8/-8

Light/dark styling parity for spacing panel

• Converts spacing panel colors/borders to light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/SpacingPanel.svelte

ThemesPanel.svelteLight/dark styling parity for themes panel +18/-18

Light/dark styling parity for themes panel

• Updates themes management UI to support light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/ThemesPanel.svelte

TypographyPanel.svelteTheme-aware select option backgrounds + light-mode typography UI +101/-96

Theme-aware select option backgrounds + light-mode typography UI

• Adds 'themeState'-derived '<option>' background inline styling and updates typography controls/samples for light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/TypographyPanel.svelte

WcagPanel.svelteTheme-aware selects + light-mode WCAG UI and status colors +37/-32

Theme-aware selects + light-mode WCAG UI and status colors

• Adds 'themeState'-derived '<option>' background inline styling and updates WCAG status colors for light+dark readability. Converts panel UI and previews to light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/panels/WcagPanel.svelte

PreviewPanel.svelteLight-mode styling for preview chrome and toolbar +20/-20

Light-mode styling for preview chrome and toolbar

• Updates preview panel backgrounds, toolbars, segmented controls, and split-view headings to be light by default with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/shell/PreviewPanel.svelte

SidebarNav.svelteLight-mode styling for sidebar navigation rail +4/-4

Light-mode styling for sidebar navigation rail

• Converts sidebar background, borders, and hover states to light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/shell/SidebarNav.svelte

StatusBar.svelteLight-mode styling for status bar +4/-4

Light-mode styling for status bar

• Updates status bar background/borders and text colors for light mode with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/shell/StatusBar.svelte

StudioHeader.svelteAdd theme toggle button and light-mode header styling +36/-19

Add theme toggle button and light-mode header styling

• Adds Sun/Moon icons and a toggle button wired to 'themeState'/'toggleTheme'. Updates header colors, separators, and button states for light defaults with 'dark:' overrides.

SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte

theme.svelte.tsIntroduce persisted Studio chrome theme state (light/dark) +74/-0

Introduce persisted Studio chrome theme state (light/dark)

• Implements light/dark state with OS-default behavior until user override, persistence via localStorage, and live 'prefers-color-scheme' updates. Exposes 'bindThemeRoot', 'setTheme', and 'toggleTheme' to control a '.dark' class on the theme root.

SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts

main.tsBind theme root pre-mount to prevent wrong-themed first paint +4/-0

Bind theme root pre-mount to prevent wrong-themed first paint

• Calls 'bindThemeRoot(target)' before mounting the Svelte app so the correct theme class is present on first render.

SLASHED-for-WP/admin-app/src/main.ts

Other (4) +85 / -76
.vendored-manifest.jsonUpdate vendoring metadata and add theme module entry +55/-51

Update vendoring metadata and add theme module entry

• Switches manifest sourcing to local paths and updates sync timestamp. Adds the newly vendored 'src/lib/theme.svelte.ts' to the tracked file list.

SLASHED-for-WP/admin-app/.vendored-manifest.json

app.cssAdd Tailwind custom 'dark' variant keyed off '.dark' class +5/-0

Add Tailwind custom 'dark' variant keyed off '.dark' class

• Defines a '.dark'-class-based custom variant for Tailwind and documents separation from the framework’s '[data-theme]' token mode.

SLASHED-for-WP/admin-app/src/app.css

app.cssRebuild compiled admin-app CSS bundle +1/-1

Rebuild compiled admin-app CSS bundle

• Updates generated Tailwind output to include the new dark variant and light-mode styling across the Studio UI.

SLASHED-for-WP/assets/admin-app/app.css

app.jsRebuild compiled admin-app JS bundle +24/-24

Rebuild compiled admin-app JS bundle

• Updates the built SPA bundle to include theme-state initialization and the header toggle behavior.

SLASHED-for-WP/assets/admin-app/app.js

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 5 rules

Grey Divider


Remediation recommended

1. Overlay option theme mismatch 🐞 Bug ≡ Correctness
Description
Several panels derive native <option> background color from themeState, but the WordPress
front-end overlay is forced into a dark Tailwind context via a hardcoded dark class and never
synchronizes themeState to dark. On pages where the admin app isn’t mounted (so no theme root is
bound), themeState stays storage/OS-derived (often light), producing inconsistent dropdown option
styling in the dark overlay (browser-dependent severity).
Code

SLASHED-for-WP/admin-app/src/components/inputs/ClampField.svelte[R9-16]

+  import { themeState } from '../../lib/theme.svelte';
+
  type RatioPreset = { label: string; value: number };

+  // <option> only reliably accepts a background via inline style (no dark:
+  // variant support), so it's derived from the chrome theme directly.
+  let optionBg = $derived(themeState.value === 'dark' ? '#16161e' : '#ffffff');
+
Relevance

⭐⭐ Medium

No historical evidence on overlay themeState syncing or <option> background mismatch in overlay
context.

PR-#122
PR-#127

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The overlay is explicitly pinned to a dark Tailwind context via a dark class, but themeState is
initialized from storage/OS and only changes via setTheme/toggleTheme; since the overlay mount
path doesn’t bind a theme root or set a theme, themeState can remain light while overlay UI is
dark. Components like ClampField then compute <option> inline background color from themeState,
creating a mismatch in the overlay.

SLASHED-for-WP/admin-app/src/AppOverlay.svelte[322-327]
SLASHED-for-WP/admin-app/src/plugin-main.ts[34-58]
SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts[12-59]
SLASHED-for-WP/admin-app/src/components/inputs/ClampField.svelte[9-16]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The WP front-end overlay forces a dark UI via a hardcoded `dark` class, but components compute some native `<option>` styling from `themeState`, which can remain light/system-derived when the main admin app is not mounted. This leads to inconsistent dropdown styling in the overlay.

## Issue Context
- The overlay is mounted on pages where `main.ts` often does not mount anything, so `bindThemeRoot()` is never called.
- Panels use `themeState` to set inline `<option>` backgrounds because Tailwind dark variants don’t reliably apply to `<option>`.

## Fix Focus Areas
- Add a non-persisting API to set theme and stop following the system (e.g. `setTheme(t, { persist: false })` or `forceTheme(t)`), so the overlay can pin `themeState` to `'dark'` without writing `localStorage`.
- Call that API from the overlay mount path (only when `#slashed-frontend-overlay` exists), before/when mounting `AppOverlay`.

### Fix Focus Areas (code references)
- SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts[12-59]
- SLASHED-for-WP/admin-app/src/plugin-main.ts[34-58]
- SLASHED-for-WP/admin-app/src/components/inputs/ClampField.svelte[9-16]
- SLASHED-for-WP/admin-app/src/AppOverlay.svelte[322-327]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. App.svelte vendored file modified 📘 Rule violation § Compliance
Description
SLASHED-for-WP/admin-app/src/App.svelte is listed as a vendored file in .vendored-manifest.json,
but this PR changes it. This violates the rule prohibiting edits to files tracked as vendored
artifacts.
Code

SLASHED-for-WP/admin-app/src/App.svelte[274]

+<div class="{embedded ? 'w-full h-full' : 'w-screen h-screen'} flex flex-col overflow-hidden bg-slate-50 dark:bg-[#0a0a0f] text-slate-800 dark:text-slate-200 font-sans">
Relevance

⭐ Low

Vendored files get updated via sync; App.svelte/.vendored-manifest.json edits merged repeatedly
(e.g., #124, #123).

PR-#124
PR-#123
PR-#111

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The vendored manifest explicitly lists src/App.svelte as a vendored file, and the PR modifies that
same file (e.g., the root container classes at line 274). Under the checklist rule, any modification
to a manifest-listed file is a violation.

Rule 1514148: Do not modify vendored files listed in .vendored-manifest.json
SLASHED-for-WP/admin-app/.vendored-manifest.json[9-17]
SLASHED-for-WP/admin-app/src/App.svelte[260-275]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
This PR modifies a file (`SLASHED-for-WP/admin-app/src/App.svelte`) that is explicitly listed as vendored in `SLASHED-for-WP/admin-app/.vendored-manifest.json`, which the checklist forbids.

## Issue Context
Per the vendoring policy, changes to vendored files must be made in the upstream framework source and then brought in via the vendoring/sync mechanism, rather than being edited directly in this repository.

## Fix Focus Areas
- SLASHED-for-WP/admin-app/.vendored-manifest.json[9-17]
- SLASHED-for-WP/admin-app/src/App.svelte[260-275]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +9 to +16
import { themeState } from '../../lib/theme.svelte';

type RatioPreset = { label: string; value: number };

// <option> only reliably accepts a background via inline style (no dark:
// variant support), so it's derived from the chrome theme directly.
let optionBg = $derived(themeState.value === 'dark' ? '#16161e' : '#ffffff');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Overlay option theme mismatch 🐞 Bug ≡ Correctness

Several panels derive native <option> background color from themeState, but the WordPress
front-end overlay is forced into a dark Tailwind context via a hardcoded dark class and never
synchronizes themeState to dark. On pages where the admin app isn’t mounted (so no theme root is
bound), themeState stays storage/OS-derived (often light), producing inconsistent dropdown option
styling in the dark overlay (browser-dependent severity).
Agent Prompt
## Issue description
The WP front-end overlay forces a dark UI via a hardcoded `dark` class, but components compute some native `<option>` styling from `themeState`, which can remain light/system-derived when the main admin app is not mounted. This leads to inconsistent dropdown styling in the overlay.

## Issue Context
- The overlay is mounted on pages where `main.ts` often does not mount anything, so `bindThemeRoot()` is never called.
- Panels use `themeState` to set inline `<option>` backgrounds because Tailwind dark variants don’t reliably apply to `<option>`.

## Fix Focus Areas
- Add a non-persisting API to set theme and stop following the system (e.g. `setTheme(t, { persist: false })` or `forceTheme(t)`), so the overlay can pin `themeState` to `'dark'` without writing `localStorage`.
- Call that API from the overlay mount path (only when `#slashed-frontend-overlay` exists), before/when mounting `AppOverlay`.

### Fix Focus Areas (code references)
- SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts[12-59]
- SLASHED-for-WP/admin-app/src/plugin-main.ts[34-58]
- SLASHED-for-WP/admin-app/src/components/inputs/ClampField.svelte[9-16]
- SLASHED-for-WP/admin-app/src/AppOverlay.svelte[322-327]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

- Ignore admin-app/src/app.css in stylelint: it's entirely vendored
  from the framework's Tailwind v4 setup (@custom-variant, an at-rule
  this project's stylelint-config-standard doesn't know), same as how
  the framework's own .stylelintrc.json excludes configurator/ entirely.
  Was failing "Lint, test, version & drift checks" CI.
- Pin themeState to 'dark' when mounting the WP frontend overlay
  (plugin-main.ts, not vendored). The overlay's shell is hardcoded to
  Tailwind's dark class and never gets a light-mode pass, but
  components that read themeState.value directly for native elements
  (e.g. ClampField's <option> background, which can't take a dark:
  class variant) were left following the OS/wp-admin-saved preference
  instead, since nothing in the overlay's mount path touched it
  (Qodo review finding).
@jackgranatowski
jackgranatowski force-pushed the claude/sync-studio-light-mode branch from 57a8b96 to 67cb731 Compare July 3, 2026 14:39
@coderabbitai coderabbitai Bot added the codex label Jul 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
SLASHED-for-WP/admin-app/src/components/panels/LayoutPanel.svelte (1)

4-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider centralizing the optionBg derivation.

This exact optionBg derived value (and its comment) is duplicated verbatim across LayoutPanel.svelte, MotionPanel.svelte, TypographyPanel.svelte, WcagPanel.svelte, and likely other panels in this rollout. Consider exporting a shared optionBg derived (or a helper function) from theme.svelte.ts alongside themeState so all consumers import one implementation instead of re-declaring it.

♻️ Example centralization in theme.svelte.ts
 export const themeState = $state<{ value: Theme }>({ value: stored ?? systemTheme() });
+
+// <option> only reliably accepts a background via inline style (no dark:
+// variant support), so panels derive it from the chrome theme directly.
+export const optionBg = $derived(themeState.value === 'dark' ? '`#16161e`' : '`#ffffff`');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SLASHED-for-WP/admin-app/src/components/panels/LayoutPanel.svelte` around
lines 4 - 8, The optionBg derived value and its explanatory comment are
duplicated across multiple panel components, so centralize that logic in the
shared theme module. Move the shared option background derivation into
theme.svelte.ts alongside themeState as an exported derived/helper, then update
LayoutPanel.svelte and the other panel components (such as MotionPanel.svelte,
TypographyPanel.svelte, and WcagPanel.svelte) to import and use that single
implementation instead of re-declaring it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@SLASHED-for-WP/admin-app/src/components/inputs/SliderRow.svelte`:
- Around line 88-98: The dark-mode helper text in SliderRow.svelte is using the
wrong shade class on the `default: {rawDefault}` paragraph, making it too dark
in dark mode. Update the conditional helper line inside `SliderRow` so the dark
theme token is a lighter slate value instead of `dark:text-slate-700`, keeping
the default label readable while preserving the existing light-mode styling.

In `@SLASHED-for-WP/admin-app/src/components/panels/CheatsheetPanel.svelte`:
- Around line 92-104: The search input in CheatsheetPanel.svelte is missing a
dark-mode placeholder style, so the hint stays too dim on dark backgrounds.
Update the search box class list on the input element to include a dark
placeholder variant alongside the existing placeholder:text-slate-600, keeping
the styling consistent with the rest of the dark theme. Use the input’s existing
class attribute in CheatsheetPanel.svelte to locate the fix.

In `@SLASHED-for-WP/admin-app/src/components/panels/HomePanel.svelte`:
- Around line 158-165: The quick-save input in HomePanel.svelte is missing a
dark-mode placeholder style, so its prompt is too low-contrast on the dark
background. Update the input class list next to the quick-save button to include
a dark placeholder variant alongside the existing placeholder:text-slate-600
styling, keeping the current visual design consistent in both themes.

In `@SLASHED-for-WP/admin-app/src/components/panels/ThemesPanel.svelte`:
- Around line 48-54: The save form in ThemesPanel.svelte has dark-mode contrast
issues: the Theme name input placeholder and the empty-state copy still use
light-only slate colors on dark surfaces. Update the input’s placeholder styling
and the empty-state text styles in ThemesPanel so they use appropriate dark-mode
variants, keeping the save form consistent with the rest of the panel.

In `@SLASHED-for-WP/admin-app/src/plugin-main.ts`:
- Around line 44-53: The dark-theme pin in plugin-main’s theme setup is being
undone because assigning themeState.value = 'dark' still leaves system following
active. Update the theme initialization to use the existing pinning logic or
equivalent in themeState/bindThemeRoot so followSystem is disabled while the
overlay is open, instead of doing a raw value assignment.

---

Nitpick comments:
In `@SLASHED-for-WP/admin-app/src/components/panels/LayoutPanel.svelte`:
- Around line 4-8: The optionBg derived value and its explanatory comment are
duplicated across multiple panel components, so centralize that logic in the
shared theme module. Move the shared option background derivation into
theme.svelte.ts alongside themeState as an exported derived/helper, then update
LayoutPanel.svelte and the other panel components (such as MotionPanel.svelte,
TypographyPanel.svelte, and WcagPanel.svelte) to import and use that single
implementation instead of re-declaring it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b6ce5c7-fac3-4e7d-afd5-6b61bee5bc84

📥 Commits

Reviewing files that changed from the base of the PR and between 331c7ab and 67cb731.

📒 Files selected for processing (40)
  • .stylelintrc.json
  • SLASHED-for-WP/admin-app/.vendored-manifest.json
  • SLASHED-for-WP/admin-app/src/App.svelte
  • SLASHED-for-WP/admin-app/src/AppOverlay.svelte
  • SLASHED-for-WP/admin-app/src/app.css
  • SLASHED-for-WP/admin-app/src/components/CommandPalette.svelte
  • SLASHED-for-WP/admin-app/src/components/DomainPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/inputs/ClampField.svelte
  • SLASHED-for-WP/admin-app/src/components/inputs/ColorInput.svelte
  • SLASHED-for-WP/admin-app/src/components/inputs/OklchColorDesk.svelte
  • SLASHED-for-WP/admin-app/src/components/inputs/PowerKnobRow.svelte
  • SLASHED-for-WP/admin-app/src/components/inputs/RangeWithNumber.svelte
  • SLASHED-for-WP/admin-app/src/components/inputs/SliderRow.svelte
  • SLASHED-for-WP/admin-app/src/components/inputs/TokenRow.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/AllTokensTab.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/BordersPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/CheatsheetPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/ColorsPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/EffectsPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/ExportPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/GenericTokenPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/HomePanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/LayoutPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/MacrosPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/MiscPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/MotionPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/ShadowsPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/SpacingPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/ThemesPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/TypographyPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/panels/WcagPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/shell/PreviewPanel.svelte
  • SLASHED-for-WP/admin-app/src/components/shell/SidebarNav.svelte
  • SLASHED-for-WP/admin-app/src/components/shell/StatusBar.svelte
  • SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte
  • SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts
  • SLASHED-for-WP/admin-app/src/main.ts
  • SLASHED-for-WP/admin-app/src/plugin-main.ts
  • SLASHED-for-WP/assets/admin-app/app.css
  • SLASHED-for-WP/assets/admin-app/app.js

Comment thread SLASHED-for-WP/admin-app/src/components/inputs/SliderRow.svelte
Comment thread SLASHED-for-WP/admin-app/src/components/panels/CheatsheetPanel.svelte Outdated
Comment thread SLASHED-for-WP/admin-app/src/components/panels/HomePanel.svelte Outdated
Comment thread SLASHED-for-WP/admin-app/src/components/panels/ThemesPanel.svelte
Comment thread SLASHED-for-WP/admin-app/src/plugin-main.ts
- Switch the frontend overlay's theme pin from a raw themeState.value
  assignment to forceTheme(), now that SLASHED#512 (which added it) is
  merged. The raw assignment left followSystem enabled, so a later OS
  prefers-color-scheme change could flip the overlay back to light
  while it's open (CodeRabbit review finding).
- Sync 4 dark-mode contrast fixes from the framework
  (codeslash-dev/SLASHED#513): SliderRow's inverted helper-text shade,
  and missing dark:placeholder/text variants in CheatsheetPanel,
  HomePanel, and ThemesPanel.
@jackgranatowski
jackgranatowski merged commit 2e24aa9 into main Jul 3, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants