Skip to content

Add theme change button and fix HUD problem#442

Closed
uunaigarr wants to merge 4 commits intosiddharthvaddem:mainfrom
uunaign:add-theme-change-button
Closed

Add theme change button and fix HUD problem#442
uunaigarr wants to merge 4 commits intosiddharthvaddem:mainfrom
uunaign:add-theme-change-button

Conversation

@uunaigarr
Copy link
Copy Markdown

@uunaigarr uunaigarr commented Apr 13, 2026

Pull Request

Description

This PR implements full light/dark theme support across the app UI.

The app was previously designed as a dark-only experience. In this change, theme support is extended so the main editor, timeline, dialogs, pre-editor HUD, source picker, and shared UI elements all respond consistently to the selected theme. The update also improves contrast and text legibility in both modes by replacing remaining dark-only surfaces and hardcoded colors with theme-aware styling.

In addition, the recording HUD was adjusted so its controls behave better while recording:

the record button no longer causes the bar to expand unexpectedly
recording-only controls have room to appear without pushing other actions off-screen
non-essential actions are hidden while recording to keep the layout stable

Motivation

It felt like a worthwhile improvement to implement light/dark theme support and make the overall UI look cleaner and more consistent.

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup
  • Documentation Update
  • Other (please specify)

Related Issue(s)

When recording, the hud would expand and looked wrong.

Screenshots / Video

Screenshot (if applicable):

Bug fix:

Before:

The bug to fix

After:

The bug fixed

New feature:

Dark theme

Toggle button

Light theme

Testing

Git pull code

npm install
npm run dev

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added theme switching capability allowing users to toggle between light and dark modes
    • User theme preference is automatically saved and persists across sessions
  • Style

    • Redesigned UI styling across the entire application for improved visual consistency
    • Enhanced component appearance with refined design tokens for better overall visual coherence

uunaign added 2 commits April 13, 2026 18:37
- add light theme support across editor panels, dialogs, timeline and recording HUD
- replace dark-only surfaces and low-contrast text with theme-aware tokens
- fix recorder HUD layout so the record button no longer pushes side controls off-screen
- hide open video/open project actions while recording to make room for recording controls
- add light theme support across editor panels, dialogs, timeline and recording HUD
- replace remaining dark-only surfaces and low-contrast text with theme-aware tokens
- fix recorder HUD layout so the record button no longer pushes side controls off-screen
- hide open video/open project actions while recording to make room for recording controls
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 13, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new theme system with light/dark mode support via a new ThemeContext, adds comprehensive CSS design tokens for semantic styling, and refactors the codebase to replace hardcoded Tailwind color classes with these new token-based utility classes across ~25 components. The Toaster now respects the active theme dynamically rather than always being dark.

Changes

Cohort / File(s) Summary
Theme Infrastructure
src/contexts/ThemeContext.tsx, src/index.css, tsconfig.json
New ThemeContext with localStorage-backed theme persistence and CSS class application to document root. Added ~15 editor design tokens and utility classes (.editor-panel, .editor-text, etc.) covering panels, text, borders, and hover states; also added "glass" tokens for source selector styling. Updated TypeScript alias path resolution.
App Root
src/App.tsx
Wrapped app tree with new ThemeProvider. Replaced static theme="dark" Toaster with new ToasterWrapper component that reads theme from useTheme() and applies it dynamically.
Launch HUD UI
src/components/launch/LaunchWindow.tsx, src/components/launch/SourceSelector.module.css
Replaced hardcoded white/gradient styling with token-based classes across HUD pills, buttons, and selectors. Updated CSS variables in .glassContainer, .icon, .name to use --glass-* tokens instead of RGBA literals.
Shared UI Components
src/components/ui/accordion.tsx, src/components/ui/audio-level-meter.tsx, src/components/ui/switch.tsx, src/components/ui/tooltip.tsx
Migrated from slate/white hardcoded colors to editor-* and theme-based token classes. Updated Switch thumb and unchecked states to use bg-background and muted tokens; Accordion borders/text to editor-border and editor-text-*; Tooltip to editor-tooltip; audio meter fallback to bg-muted.
Video Editor Core & Dialogs
src/components/video-editor/VideoEditor.tsx, src/components/video-editor/AddCustomFontDialog.tsx, src/components/video-editor/ExportDialog.tsx, src/components/video-editor/ShortcutsConfigDialog.tsx, src/components/video-editor/TutorialHelp.tsx
Integrated useTheme() in VideoEditor with theme toggle button (Sun/Moon icon). Replaced dark theme hardcoded hex/slate classes with editor-* tokens throughout. Updated dialog backgrounds, text, and controls to use semantic classes.
Video Editor Settings Panels
src/components/video-editor/SettingsPanel.tsx, src/components/video-editor/AnnotationSettingsPanel.tsx, src/components/video-editor/BlurSettingsPanel.tsx, src/components/video-editor/FormatSelector.tsx, src/components/video-editor/PlaybackControls.tsx, src/components/video-editor/KeyboardShortcutsHelp.tsx
Bulk styling refactor from hardcoded slate/white/opacity classes to token-based utility classes (editor-panel*, editor-text*, editor-border, bg-background, border-input, bg-accent). Updated buttons, form controls, text emphasis, and hover states consistently.
Timeline Components
src/components/video-editor/timeline/TimelineEditor.tsx, src/components/video-editor/timeline/TimelineWrapper.tsx, src/components/video-editor/timeline/Item.tsx, src/components/video-editor/timeline/Row.tsx, src/components/video-editor/timeline/Subrow.tsx
Replaced hardcoded border/background/text colors with editor-* tokens and foreground-opacity equivalents. Updated inline style={{ color: "#fff" }} to CSS variable var(--editor-text-strong). Adjusted grid background to support light mode via dark:bg-* fallback.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Suggested reviewers

  • siddharthvaddem
  • FabLrc

🌓 goodbye hardcoded hex nightmares,
hello tokens that actually care,
light and dark in perfect sync,
no more "magic #1a1a1c" brink,
design system's finally here ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title captures the two main changes: theme support and HUD layout fixes, though it undersells the scope of the theming work.
Description check ✅ Passed Description covers all required sections with clear motivation, type of change, screenshots, testing steps, and completed checklist. Comprehensively explains both the new feature and bug fix.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9450834f9a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread package-lock.json
Comment on lines 5035 to +5037
"peerDependencies": {
"picomatch": "^3 || ^4"
"msw": "^2.4.9",
"vite": "^6.0.0 || ^7.0.0-0"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore missing nested vite records in lockfile

This lockfile edit removes the nested vite package entries under @vitest/browser/@vitest/browser-playwright while keeping @vitest/mocker records that still declare a vite peer, which makes the lock inconsistent with itself. On this commit, npm ci --dry-run --ignore-scripts fails with Missing: vite@ from lock file, so clean installs in CI or fresh clones will fail until the lockfile is regenerated correctly.

Useful? React with 👍 / 👎.

Comment thread .gitignore Outdated
# Vitest browser mode screenshots
__screenshots__/ No newline at end of file
__screenshots__/
package-lock.json
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep package-lock.json tracked by Git

Adding package-lock.json to .gitignore will cause future lockfile updates to be silently omitted from commits, which undermines reproducible installs for this npm app and makes lock/package drift more likely. Given this same change set already introduces a lock mismatch, ignoring the lockfile will make it harder to prevent or review similar breakages.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/components/video-editor/VideoEditor.tsx (1)

288-309: ⚠️ Potential issue | 🟠 Major

Keep webcamSizePreset in the project snapshot.

saveProject() and applyLoadedProject() still persist this field, but currentProjectSnapshot dropped it here. That means a webcam size tweak can stop affecting hasUnsavedChanges, so the editor may happily say “nothing to save” and lose that change on close.

🐛 Proposed fix
 		return createProjectSnapshot(currentProjectMedia, {
 			wallpaper,
 			shadowIntensity,
 			showBlur,
 			motionBlurAmount,
 			borderRadius,
 			padding,
 			cropRegion,
 			zoomRegions,
 			trimRegions,
 			speedRegions,
 			annotationRegions,
 			aspectRatio,
 			webcamLayoutPreset,
 			webcamMaskShape,
+			webcamSizePreset,
 			webcamPosition,
 			exportQuality,
 			exportFormat,
 			gifFrameRate,
 			gifLoop,
 			gifSizePreset,
 		});
 	}, [
 		currentProjectMedia,
 		wallpaper,
 		shadowIntensity,
 		showBlur,
 		motionBlurAmount,
 		borderRadius,
 		padding,
 		cropRegion,
 		zoomRegions,
 		trimRegions,
 		speedRegions,
 		annotationRegions,
 		aspectRatio,
 		webcamLayoutPreset,
 		webcamMaskShape,
+		webcamSizePreset,
 		webcamPosition,
 		exportQuality,
 		exportFormat,
 		gifFrameRate,
 		gifLoop,
 		gifSizePreset,
 	]);

Also applies to: 310-332

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/VideoEditor.tsx` around lines 288 - 309, The
project snapshot creation omitted webcamSizePreset causing webcam size changes
to be ignored for unsaved-change detection; update all places that call
createProjectSnapshot (e.g., the call using currentProjectMedia and the other
call around lines 310–332) to include the webcamSizePreset property alongside
webcamLayoutPreset, webcamMaskShape, and webcamPosition so the snapshot contains
webcamSizePreset; ensure the same property name (webcamSizePreset) is passed
into createProjectSnapshot wherever project snapshots are constructed.
src/components/video-editor/AnnotationSettingsPanel.tsx (1)

376-388: ⚠️ Potential issue | 🟠 Major

These color pickers still force a dark popover.

Each PopoverContent is pinned to bg-[#1a1a1c], so opening the palette in light mode drops a dark slab into an otherwise themed panel. kinda defeats the theme pass right where users are staring. Swap these to the same semantic surface tokens (bg-popover, editor-panel-soft, etc.) so the picker actually follows the selected theme.

Also applies to: 410-427, 570-584

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/AnnotationSettingsPanel.tsx` around lines 376 -
388, PopoverContent instances for the color picker are hardcoded to
bg-[`#1a1a1c`], forcing a dark background; find the PopoverContent components
(used alongside PopoverTrigger in AnnotationSettingsPanel, e.g., the instances
wrapping the color palette around the Button) and replace the literal
bg-[`#1a1a1c`] with the appropriate semantic surface tokens such as bg-popover or
editor-panel-soft (or the project's equivalent theme token) so the popover
follows light/dark themes; apply the same change to the other PopoverContent
occurrences referenced in the review (the blocks around lines ~410-427 and
~570-584) to ensure theme consistency across all color pickers.
src/components/video-editor/SettingsPanel.tsx (2)

1363-1382: ⚠️ Potential issue | 🟠 Major

Active export-format tabs lose contrast in light mode.

The active state is only bg-[#34B27B]/10 plus text-white. On a light surface that’s basically white text on a barely-tinted chip. Either make the active chip solid green or keep the subtle background and switch the text to a dark/brand color.

🎨 One simple fix
 							exportFormat === "mp4"
-								? "bg-[`#34B27B`]/10 border-[`#34B27B`]/50 text-white"
+								? "bg-[`#34B27B`] border-[`#34B27B`] text-white"
 								: "bg-background border-input editor-text-muted hover:bg-accent hover:text-foreground",
@@
 							exportFormat === "gif"
-								? "bg-[`#34B27B`]/10 border-[`#34B27B`]/50 text-white"
+								? "bg-[`#34B27B`] border-[`#34B27B`] text-white"
 								: "bg-background border-input editor-text-muted hover:bg-accent hover:text-foreground",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/SettingsPanel.tsx` around lines 1363 - 1382, The
active export-format button styling (in the buttons using exportFormat and
onExportFormatChange) uses a very light bg-[`#34B27B`]/10 with text-white, causing
poor contrast in light mode; update the active class for the buttons (the
className logic that checks exportFormat === "mp4" / "gif") to use a
higher-contrast combination — either make the active chip a solid brand green
background (e.g., stronger bg like bg-[`#34B27B`] or equivalent token) with
appropriate foreground (white) OR keep the subtle bg and switch the active text
color to a dark/brand color (not white) so the label (t("exportFormat.mp4") /
gif) is readable; ensure the change is applied to both export-format buttons
(the ones using exportFormat, onExportFormatChange, Film, and getTestId).

811-829: ⚠️ Potential issue | 🟠 Major

A few section surfaces are still dark-mode-only.

These containers still use bg-white/[0.02] and the layout preset trigger still uses bg-black/20, so light theme ends up with washed-out cards and a muddy select. I’d swap these to the same semantic surfaces used elsewhere (editor-panel-soft, bg-background, bg-popover, etc.) before calling the theme pass done.

Also applies to: 955-964, 1069-1084

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/SettingsPanel.tsx` around lines 811 - 829,
Several containers still use hardcoded dark-mode colors (bg-white/[0.02],
bg-black/20) causing washed-out cards in light theme; update the AccordionItem
with value="layout" and the SelectTrigger used for webcamLayoutPreset to use the
semantic surface classes used elsewhere (e.g., replace bg-white/[0.02] with
editor-panel-soft or bg-background, and replace bg-black/20 with bg-popover or
editor-panel-soft) so themes render correctly. Apply the same replacements to
the other similar sections noted (the other AccordionItem/select blocks
referenced) so all cards and triggers use the shared semantic surface classes
instead of hardcoded color utilities.
🧹 Nitpick comments (4)
src/components/video-editor/timeline/TimelineEditor.tsx (1)

669-669: Consider tokenizing the grid gradient too.

Line 669 still hardcodes color values in arbitrary Tailwind syntax. lowkey risky for future theme tuning; a shared token/class would keep this fully aligned with the rest of the migration.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/timeline/TimelineEditor.tsx` at line 669, The
gradient background on the grid is using hardcoded color values in the className
on the div inside TimelineEditor, so replace that inline Tailwind arbitrary
colors with a shared theme token or utility class (e.g., create a CSS rule or
Tailwind plugin class like .bg-grid-gradient that references design tokens / CSS
variables such as --color-grid and --color-grid-dark) and update the div in
TimelineEditor.tsx to use that class instead of the long
bg-[linear-gradient(...)] string; ensure the new token/class covers both light
and dark variants so theme tuning stays centralized and consistent with other
components.
src/components/video-editor/BlurSettingsPanel.tsx (1)

67-67: Nit: cleaner to avoid hardcoded white in hover border.

hover:border-white/20 is kinda off-pattern now that this panel is tokenized; using hover:border-border keeps light/dark behavior consistent.

♻️ Small consistency tweak
-										: "bg-background border-input hover:bg-accent hover:border-white/20",
+										: "bg-background border-input hover:bg-accent hover:border-border",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/BlurSettingsPanel.tsx` at line 67, In
BlurSettingsPanel (the component that builds the className string containing
"bg-background border-input hover:bg-accent hover:border-white/20") replace the
hardcoded "hover:border-white/20" token with the design token
"hover:border-border" so the hover border uses the tokenized color and respects
light/dark theming; keep the rest of the class string intact.
src/index.css (1)

188-192: Tokenize .editor-kbd accent color instead of hardcoding it.

#34b27b on Line 191 bypasses the new token system. recommend a semantic var (e.g. --editor-accent) for consistent theming/tuning.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.css` around lines 188 - 192, Replace the hardcoded color in the
.editor-kbd rule with a semantic CSS variable so theming works consistently:
change the color property in .editor-kbd to use a token like --editor-accent
(fallback optional) and add/update the token declaration where global CSS
variables are defined (the same place other vars like --editor-hover /
--editor-border-strong live) so consumers can tune the accent color centrally.
src/contexts/ThemeContext.tsx (1)

53-61: Avoid double-applying the theme class on each toggle.

applyTheme runs in setTheme (Line 60) and again in the effect (Line 69). Works, but it’s redundant DOM churn.

nit: cleaner single-source apply path
 const setTheme = useCallback((newTheme: Theme) => {
 	setThemeState(newTheme);
 	try {
 		localStorage.setItem(THEME_STORAGE_KEY, newTheme);
 	} catch {
 		// localStorage may be unavailable
 	}
-	applyTheme(newTheme);
 }, []);

Also applies to: 67-70

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/contexts/ThemeContext.tsx` around lines 53 - 61, The theme is being
applied twice: once inside setTheme and again in the downstream effect; remove
the redundant call by having setTheme only update state and storage (keep
setThemeState and localStorage logic) and let the existing effect that watches
themeState call applyTheme centrally; update references to the functions
setTheme and applyTheme (and the effect that currently calls applyTheme) so
there is a single source of DOM updates for theme changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.gitignore:
- Line 37: Remove the `package-lock.json` entry from `.gitignore` and commit the
lockfile so npm installs are deterministic: edit `.gitignore` to delete the line
containing "package-lock.json", then add and commit `package-lock.json` (git add
package-lock.json && git commit -m "Track package-lock.json"); confirm
`package.json` still declares npm as the package manager and push the commit so
CI/prod and local dev use the same lockfile.

In `@src/components/launch/LaunchWindow.tsx`:
- Around line 244-245: The styled <option> elements in LaunchWindow.tsx (inside
the select rendering where getLocaleName(loc) is used) rely on classes like
bg-popover and text-foreground which are not consistently applied on native
selects (especially macOS/Windows); update the select rendering to either remove
option-level styles and apply safe select-level styles or replace this native
<select> with the existing custom dropdown component used elsewhere so contrast
is reliable across platforms, then test the locale dropdown (the option loop
using getLocaleName(loc)) in macOS and Windows light/dark themes to ensure
legibility and adjust colors or fallback styles accordingly; also apply the same
change to the other occurrences noted (the option blocks at the other two
locations).

In `@src/components/launch/SourceSelector.module.css`:
- Around line 14-15: The .selected card state still uses a hardcoded dark
gradient; update the .selected rule in SourceSelector.module.css to use design
tokens (e.g., reuse --glass-card and related token variables like --glass-border
or introduce a new token such as --glass-card-selected) instead of the
near-black gradient so the selected card responds correctly to light/dark
themes; modify the .selected selector to reference those CSS variables and
ensure any border/shadow values also use tokens for consistent theming.

In `@src/components/video-editor/BlurSettingsPanel.tsx`:
- Around line 94-99: Replace the hardcoded dark color class "text-slate-300" in
BlurSettingsPanel.tsx with the theme-aware text token used elsewhere (e.g.,
text-muted-foreground or the project's equivalent) so the label contrast adapts
to light/dark themes; update both occurrences—the span wrapping
t("annotation.blurIntensity") and the sibling span with "editor-text-muted
font-mono" (the second instance around lines ~130-133)—to use the theme token
instead of "text-slate-300".

In `@src/components/video-editor/ExportDialog.tsx`:
- Around line 122-123: ExportDialog currently derives the filename using
exportedFilePath.split("/").pop(), which fails on Windows paths; update the
extraction to be cross-platform (e.g., implement a small helper like getBasename
that uses a regex or splits on both slashes/backslashes such as
exportedFilePath.split(/[\\/]/).pop(), or, if running in Node context, use
path.basename) and replace the current expression in the JSX span that
references exportedFilePath so the displayed basename works for both POSIX and
Windows paths.

In `@src/components/video-editor/VideoEditor.tsx`:
- Around line 1732-1738: The theme-toggle button (the icon-only button that
calls toggleTheme and checks theme) needs an accessible name via aria-label
sourced from i18n: import or use your existing translation hook/function (e.g.,
t or useTranslation) and set aria-label on the button to a translated string
that mirrors the title logic (e.g., aria-label={t(theme === "dark" ?
"switch_to_light_mode" : "switch_to_dark_mode")}) so screen readers get an
accessible, localized label for the toggle.

In `@src/contexts/ThemeContext.tsx`:
- Around line 37-39: The theme is being applied twice and causes a flash because
applyTheme is called synchronously in setTheme and again in a later useEffect;
replace that effect with useLayoutEffect so the DOM/class is updated before the
first paint and remove the direct call to applyTheme inside setTheme so theme
application happens only once via the layout effect; specifically, change the
effect that currently uses useEffect to useLayoutEffect (the one that reads
theme and toggles the .dark class) and delete the applyTheme call from the
setTheme implementation so setTheme only updates state.

---

Outside diff comments:
In `@src/components/video-editor/AnnotationSettingsPanel.tsx`:
- Around line 376-388: PopoverContent instances for the color picker are
hardcoded to bg-[`#1a1a1c`], forcing a dark background; find the PopoverContent
components (used alongside PopoverTrigger in AnnotationSettingsPanel, e.g., the
instances wrapping the color palette around the Button) and replace the literal
bg-[`#1a1a1c`] with the appropriate semantic surface tokens such as bg-popover or
editor-panel-soft (or the project's equivalent theme token) so the popover
follows light/dark themes; apply the same change to the other PopoverContent
occurrences referenced in the review (the blocks around lines ~410-427 and
~570-584) to ensure theme consistency across all color pickers.

In `@src/components/video-editor/SettingsPanel.tsx`:
- Around line 1363-1382: The active export-format button styling (in the buttons
using exportFormat and onExportFormatChange) uses a very light bg-[`#34B27B`]/10
with text-white, causing poor contrast in light mode; update the active class
for the buttons (the className logic that checks exportFormat === "mp4" / "gif")
to use a higher-contrast combination — either make the active chip a solid brand
green background (e.g., stronger bg like bg-[`#34B27B`] or equivalent token) with
appropriate foreground (white) OR keep the subtle bg and switch the active text
color to a dark/brand color (not white) so the label (t("exportFormat.mp4") /
gif) is readable; ensure the change is applied to both export-format buttons
(the ones using exportFormat, onExportFormatChange, Film, and getTestId).
- Around line 811-829: Several containers still use hardcoded dark-mode colors
(bg-white/[0.02], bg-black/20) causing washed-out cards in light theme; update
the AccordionItem with value="layout" and the SelectTrigger used for
webcamLayoutPreset to use the semantic surface classes used elsewhere (e.g.,
replace bg-white/[0.02] with editor-panel-soft or bg-background, and replace
bg-black/20 with bg-popover or editor-panel-soft) so themes render correctly.
Apply the same replacements to the other similar sections noted (the other
AccordionItem/select blocks referenced) so all cards and triggers use the shared
semantic surface classes instead of hardcoded color utilities.

In `@src/components/video-editor/VideoEditor.tsx`:
- Around line 288-309: The project snapshot creation omitted webcamSizePreset
causing webcam size changes to be ignored for unsaved-change detection; update
all places that call createProjectSnapshot (e.g., the call using
currentProjectMedia and the other call around lines 310–332) to include the
webcamSizePreset property alongside webcamLayoutPreset, webcamMaskShape, and
webcamPosition so the snapshot contains webcamSizePreset; ensure the same
property name (webcamSizePreset) is passed into createProjectSnapshot wherever
project snapshots are constructed.

---

Nitpick comments:
In `@src/components/video-editor/BlurSettingsPanel.tsx`:
- Line 67: In BlurSettingsPanel (the component that builds the className string
containing "bg-background border-input hover:bg-accent hover:border-white/20")
replace the hardcoded "hover:border-white/20" token with the design token
"hover:border-border" so the hover border uses the tokenized color and respects
light/dark theming; keep the rest of the class string intact.

In `@src/components/video-editor/timeline/TimelineEditor.tsx`:
- Line 669: The gradient background on the grid is using hardcoded color values
in the className on the div inside TimelineEditor, so replace that inline
Tailwind arbitrary colors with a shared theme token or utility class (e.g.,
create a CSS rule or Tailwind plugin class like .bg-grid-gradient that
references design tokens / CSS variables such as --color-grid and
--color-grid-dark) and update the div in TimelineEditor.tsx to use that class
instead of the long bg-[linear-gradient(...)] string; ensure the new token/class
covers both light and dark variants so theme tuning stays centralized and
consistent with other components.

In `@src/contexts/ThemeContext.tsx`:
- Around line 53-61: The theme is being applied twice: once inside setTheme and
again in the downstream effect; remove the redundant call by having setTheme
only update state and storage (keep setThemeState and localStorage logic) and
let the existing effect that watches themeState call applyTheme centrally;
update references to the functions setTheme and applyTheme (and the effect that
currently calls applyTheme) so there is a single source of DOM updates for theme
changes.

In `@src/index.css`:
- Around line 188-192: Replace the hardcoded color in the .editor-kbd rule with
a semantic CSS variable so theming works consistently: change the color property
in .editor-kbd to use a token like --editor-accent (fallback optional) and
add/update the token declaration where global CSS variables are defined (the
same place other vars like --editor-hover / --editor-border-strong live) so
consumers can tune the accent color centrally.
🪄 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

Run ID: 7d586542-1205-422d-a949-2a4c824592e6

📥 Commits

Reviewing files that changed from the base of the PR and between a6ae0e6 and 9450834.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • .gitignore
  • src/App.tsx
  • src/components/launch/LaunchWindow.tsx
  • src/components/launch/SourceSelector.module.css
  • src/components/launch/SourceSelector.tsx
  • src/components/ui/accordion.tsx
  • src/components/ui/audio-level-meter.tsx
  • src/components/ui/switch.tsx
  • src/components/ui/tooltip.tsx
  • src/components/video-editor/AddCustomFontDialog.tsx
  • src/components/video-editor/AnnotationSettingsPanel.tsx
  • src/components/video-editor/BlurSettingsPanel.tsx
  • src/components/video-editor/ExportDialog.tsx
  • src/components/video-editor/FormatSelector.tsx
  • src/components/video-editor/KeyboardShortcutsHelp.tsx
  • src/components/video-editor/PlaybackControls.tsx
  • src/components/video-editor/SettingsPanel.tsx
  • src/components/video-editor/ShortcutsConfigDialog.tsx
  • src/components/video-editor/TutorialHelp.tsx
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/timeline/Item.tsx
  • src/components/video-editor/timeline/Row.tsx
  • src/components/video-editor/timeline/Subrow.tsx
  • src/components/video-editor/timeline/TimelineEditor.tsx
  • src/components/video-editor/timeline/TimelineWrapper.tsx
  • src/contexts/ThemeContext.tsx
  • src/index.css
  • tsconfig.json

Comment thread .gitignore Outdated
# Vitest browser mode screenshots
__screenshots__/ No newline at end of file
__screenshots__/
package-lock.json
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify package-manager strategy before keeping package-lock.json ignored.

echo "1) Check ignore rule:"
rg -n '^package-lock\.json$' .gitignore

echo
echo "2) Discover lockfiles in repo:"
fd -a '^(package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$'

echo
echo "3) Check package manager declaration(s) in package.json files:"
rg -n '"packageManager"\s*:' --iglob 'package.json'

Repository: siddharthvaddem/openscreen

Length of output: 256


Remove package-lock.json from .gitignore

The repo explicitly declares npm as the package manager in package.json, so ignoring the lockfile is lowkey risky. Without package-lock.json tracked, installs become non-deterministic and you'll get audit drift between local dev and CI/prod. Delete line 37 and make sure the lockfile gets committed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitignore at line 37, Remove the `package-lock.json` entry from
`.gitignore` and commit the lockfile so npm installs are deterministic: edit
`.gitignore` to delete the line containing "package-lock.json", then add and
commit `package-lock.json` (git add package-lock.json && git commit -m "Track
package-lock.json"); confirm `package.json` still declares npm as the package
manager and push the commit so CI/prod and local dev use the same lockfile.

Comment thread src/components/launch/LaunchWindow.tsx Outdated
Comment on lines +14 to +15
background: var(--glass-card);
border: 1px solid var(--glass-border);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Tokenize the selected card state too.

Nice that the base card now reads from --glass-card, but .selected below still hardcodes a near-black gradient. In light mode the one card the user picks will flip right back to a dark surface, which kinda undoes the theme work for the most important state.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/launch/SourceSelector.module.css` around lines 14 - 15, The
.selected card state still uses a hardcoded dark gradient; update the .selected
rule in SourceSelector.module.css to use design tokens (e.g., reuse --glass-card
and related token variables like --glass-border or introduce a new token such as
--glass-card-selected) instead of the near-black gradient so the selected card
responds correctly to light/dark themes; modify the .selected selector to
reference those CSS variables and ensure any border/shadow values also use
tokens for consistent theming.

Comment on lines +94 to +99
<div className="mt-4 p-3 rounded-lg bg-background border border-input">
<div className="flex items-center justify-between mb-2">
<span className="text-xs font-medium text-slate-300">
{t("annotation.blurIntensity")}
</span>
<span className="text-[10px] text-slate-400 font-mono">
<span className="text-[10px] editor-text-muted font-mono">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Lowkey risky: hardcoded text-slate-300 can hurt light-theme contrast.

Line 96 and Line 131 still hardcode dark-leaning text while their containers are now theme-token based. that can make labels look washed out in light mode.

🎯 Proposed fix
-						<span className="text-xs font-medium text-slate-300">
+						<span className="text-xs font-medium editor-text">
 							{t("annotation.blurIntensity")}
 						</span>
@@
-					<div className="flex items-center gap-2 mb-2 text-slate-300">
+					<div className="flex items-center gap-2 mb-2 editor-text-muted">
 						<Info className="w-3.5 h-3.5" />
 						<span className="text-xs font-medium">{t("annotation.shortcutsAndTips")}</span>
 					</div>

Also applies to: 130-133

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/BlurSettingsPanel.tsx` around lines 94 - 99,
Replace the hardcoded dark color class "text-slate-300" in BlurSettingsPanel.tsx
with the theme-aware text token used elsewhere (e.g., text-muted-foreground or
the project's equivalent) so the label contrast adapts to light/dark themes;
update both occurrences—the span wrapping t("annotation.blurIntensity") and the
sibling span with "editor-text-muted font-mono" (the second instance around
lines ~130-133)—to use the theme token instead of "text-slate-300".

Comment on lines +122 to 123
<span className="text-xs editor-text-faint break-all max-w-xs mt-1">
{exportedFilePath.split("/").pop()}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Filename parsing is POSIX-only right now.

Line 123 uses split("/"), so Windows-style paths won’t resolve to basename correctly.

nit: cleaner cross-platform basename extraction
- {exportedFilePath.split("/").pop()}
+ {exportedFilePath.split(/[/\\]/).pop()}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<span className="text-xs editor-text-faint break-all max-w-xs mt-1">
{exportedFilePath.split("/").pop()}
<span className="text-xs editor-text-faint break-all max-w-xs mt-1">
{exportedFilePath.split(/[/\\]/).pop()}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/ExportDialog.tsx` around lines 122 - 123,
ExportDialog currently derives the filename using
exportedFilePath.split("/").pop(), which fails on Windows paths; update the
extraction to be cross-platform (e.g., implement a small helper like getBasename
that uses a regex or splits on both slashes/backslashes such as
exportedFilePath.split(/[\\/]/).pop(), or, if running in Node context, use
path.basename) and replace the current expression in the JSX span that
references exportedFilePath so the displayed basename works for both POSIX and
Windows paths.

Comment on lines +1732 to +1738
<button
type="button"
onClick={toggleTheme}
className="flex items-center justify-center p-1.5 rounded-md editor-text-muted hover:text-foreground hover:bg-accent transition-all duration-150"
title={theme === "dark" ? "Switch to light mode" : "Switch to dark mode"}
>
{theme === "dark" ? <Sun size={14} /> : <Moon size={14} />}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Give the theme toggle a real accessible name.

This is an icon-only button, so relying on title is lowkey risky: screen readers won’t consistently use it, and the label is hardcoded English anyway. Please add an aria-label sourced from i18n so the new control is actually discoverable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/VideoEditor.tsx` around lines 1732 - 1738, The
theme-toggle button (the icon-only button that calls toggleTheme and checks
theme) needs an accessible name via aria-label sourced from i18n: import or use
your existing translation hook/function (e.g., t or useTranslation) and set
aria-label on the button to a translated string that mirrors the title logic
(e.g., aria-label={t(theme === "dark" ? "switch_to_light_mode" :
"switch_to_dark_mode")}) so screen readers get an accessible, localized label
for the toggle.

Comment on lines +37 to +39
// Default to dark theme (app is designed for dark theme)
return "dark";
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "ThemeContext.tsx" -type f

Repository: siddharthvaddem/openscreen

Length of output: 101


🏁 Script executed:

cat -n src/contexts/ThemeContext.tsx

Repository: siddharthvaddem/openscreen

Length of output: 2459


🏁 Script executed:

# Check for any CSS files related to theming
fd -e css -e scss | grep -i theme || echo "No theme-related CSS found in standard locations"

Repository: siddharthvaddem/openscreen

Length of output: 118


🏁 Script executed:

# Check the entire src structure to understand styling approach
ls -la src/ 2>/dev/null | head -20

Repository: siddharthvaddem/openscreen

Length of output: 880


🏁 Script executed:

cat -n src/index.css | head -100

Repository: siddharthvaddem/openscreen

Length of output: 4320


🏁 Script executed:

cat -n src/App.css

Repository: siddharthvaddem/openscreen

Length of output: 945


🏁 Script executed:

# Check main.tsx to see how the app is bootstrapped
cat -n src/main.tsx

Repository: siddharthvaddem/openscreen

Length of output: 488


First-paint flash is kinda cursed here, and theme gets applied twice.

On mount, theme state syncs to "dark" (line 51), but the .dark class only gets added in useEffect (line 69), which runs after the browser paints. Since :root defaults to light tokens, you get a light→dark flash on cold start.

Also, setTheme calls applyTheme directly (line 60), then the state update triggers the effect which calls it again (line 69). Nit: use useLayoutEffect instead so the class applies before paint, and remove the explicit applyTheme call from setTheme to avoid double-application.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/contexts/ThemeContext.tsx` around lines 37 - 39, The theme is being
applied twice and causes a flash because applyTheme is called synchronously in
setTheme and again in a later useEffect; replace that effect with
useLayoutEffect so the DOM/class is updated before the first paint and remove
the direct call to applyTheme inside setTheme so theme application happens only
once via the layout effect; specifically, change the effect that currently uses
useEffect to useLayoutEffect (the one that reads theme and toggles the .dark
class) and delete the applyTheme call from the setTheme implementation so
setTheme only updates state.

@FabLrc
Copy link
Copy Markdown
Collaborator

FabLrc commented Apr 21, 2026

Hi,
Great work! Can you resolve the conflicts and update your branch? AIs have flagged a few interesting fixes that need to be addressed as well.
Also, many bugs have been fixed recently, so make sure the current code doesn't already address the issues you've fixed!
Thanks for your contribution :)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/launch/LaunchWindow.tsx (1)

320-344: ⚠️ Potential issue | 🟡 Minor

Tokenize the locale suggestion prompt too.

This prompt is still dark-only (bg-[rgba(...)], text-white, bg-white). In light theme it’ll look kinda cursed compared with the rest of the HUD.

🎨 Proposed cleanup
- className={`fixed top-8 left-1/2 z-30 w-[calc(100vw-1rem)] max-w-[520px] -translate-x-1/2 rounded-xl border border-white/15 bg-[rgba(20,20,28,0.95)] p-3 shadow-2xl backdrop-blur-xl text-white animate-in fade-in-0 zoom-in-95 duration-200 ${styles.electronNoDrag}`}
+ className={`fixed top-8 left-1/2 z-30 w-[calc(100vw-1rem)] max-w-[520px] -translate-x-1/2 rounded-xl editor-panel p-3 shadow-2xl backdrop-blur-xl animate-in fade-in-0 zoom-in-95 duration-200 ${styles.electronNoDrag}`}
- <div className="text-[13px] font-semibold text-white">
+ <div className="text-[13px] font-semibold text-foreground">
- <div className="mt-1 text-[11px] leading-relaxed text-white/75">
+ <div className="mt-1 text-[11px] leading-relaxed editor-text-muted">
- className="h-7 text-xs text-white/80 hover:bg-white/10 hover:text-white"
+ className="h-7 text-xs text-foreground/80 hover:bg-accent hover:text-foreground"
- className="h-7 text-xs bg-white text-[`#10121b`] hover:bg-white/90"
+ className="h-7 text-xs bg-primary text-primary-foreground hover:bg-primary/90"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/launch/LaunchWindow.tsx` around lines 320 - 344, The locale
suggestion banner in LaunchWindow uses hardcoded dark-only styling (e.g.,
bg-[rgba(...)] and text-white, and the accept button uses
bg-white/text-[`#10121b`]), so update the container and the two Buttons (the div
with the long className, and the Button instances using
dismissSystemLocaleSuggestion and acceptSystemLocaleSuggestion) to use
theme-aware classes or component props instead of fixed colors: replace the
hardcoded background, text and button color classes with Tailwind dark: and
light-appropriate classes or the app's theme tokens (ensure border color and
backdrop opacity also adapt), or switch the Buttons to a theme-aware variant so
the prompt looks correct in both light and dark modes while preserving
styles.electronNoDrag and existing spacing/animation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/launch/LaunchWindow.tsx`:
- Around line 67-75: Update the hard-coded white text tokens so child icons
inherit theme-aware colors: replace instances of "text-white/55" and any other
"text-white*" in hudAuxIconBtnClasses, hudIconBtnClasses, and windowBtnClasses
(and the similar class blocks around lines 546-612 and 617-689) with the theme
foreground token (e.g., text-foreground or text-foreground/55) or remove
explicit color to let the parent class provide color; ensure hover/disabled
styles still use appropriate opacity but no longer force white so light/dark
themes maintain contrast.

---

Outside diff comments:
In `@src/components/launch/LaunchWindow.tsx`:
- Around line 320-344: The locale suggestion banner in LaunchWindow uses
hardcoded dark-only styling (e.g., bg-[rgba(...)] and text-white, and the accept
button uses bg-white/text-[`#10121b`]), so update the container and the two
Buttons (the div with the long className, and the Button instances using
dismissSystemLocaleSuggestion and acceptSystemLocaleSuggestion) to use
theme-aware classes or component props instead of fixed colors: replace the
hardcoded background, text and button color classes with Tailwind dark: and
light-appropriate classes or the app's theme tokens (ensure border color and
backdrop opacity also adapt), or switch the Buttons to a theme-aware variant so
the prompt looks correct in both light and dark modes while preserving
styles.electronNoDrag and existing spacing/animation.
🪄 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

Run ID: df9974d7-a7b0-4cbb-b091-f86106af9631

📥 Commits

Reviewing files that changed from the base of the PR and between 71bc774 and fdc488a.

📒 Files selected for processing (8)
  • src/App.tsx
  • src/components/launch/LaunchWindow.tsx
  • src/components/launch/SourceSelector.module.css
  • src/components/video-editor/AnnotationSettingsPanel.tsx
  • src/components/video-editor/BlurSettingsPanel.tsx
  • src/components/video-editor/SettingsPanel.tsx
  • src/components/video-editor/VideoEditor.tsx
  • src/index.css
✅ Files skipped from review due to trivial changes (4)
  • src/components/video-editor/BlurSettingsPanel.tsx
  • src/components/video-editor/AnnotationSettingsPanel.tsx
  • src/index.css
  • src/components/video-editor/SettingsPanel.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/App.tsx
  • src/components/video-editor/VideoEditor.tsx
  • src/components/launch/SourceSelector.module.css

Comment on lines 67 to 75
const hudIconBtnClasses =
"flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer text-white hover:bg-white/10 hover:scale-[1.08] active:scale-95";
"flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer text-foreground hover:bg-accent hover:scale-[1.08] active:scale-95";

const hudAuxIconBtnClasses =
"flex items-center justify-center p-1.5 rounded-full transition-colors duration-150 text-white/55 hover:bg-white/10 disabled:opacity-30 disabled:cursor-not-allowed";

const windowBtnClasses =
"flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer opacity-50 hover:opacity-90 hover:bg-white/[0.08]";
"flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer opacity-50 hover:opacity-90 hover:bg-accent";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don’t let child icons override the new theme tokens.

The parent HUD classes are theme-aware now, but several child icons still force text-white*, so light mode can lose contrast. Lowkey risky for the file/open/window/recording controls.

🎨 Suggested direction
 const hudAuxIconBtnClasses =
-	"flex items-center justify-center p-1.5 rounded-full transition-colors duration-150 text-white/55 hover:bg-white/10 disabled:opacity-30 disabled:cursor-not-allowed";
+	"flex items-center justify-center p-1.5 rounded-full transition-colors duration-150 text-foreground/55 hover:bg-accent disabled:opacity-30 disabled:cursor-not-allowed";

 const windowBtnClasses =
-	"flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer opacity-50 hover:opacity-90 hover:bg-accent";
+	"flex items-center justify-center p-2 rounded-full transition-all duration-150 cursor-pointer text-foreground/70 opacity-50 hover:opacity-90 hover:bg-accent";
- : "bg-white/5 hover:bg-white/[0.08]"
+ : "bg-accent/60 hover:bg-accent"
- : getIcon("record", hasSelectedSource ? "text-white/80" : "text-white/30")}
+ : getIcon("record", hasSelectedSource ? "text-red-500" : "text-foreground/30")}
- {getIcon(paused ? "resume" : "pause", paused ? "text-amber-400" : "text-white/60")}
+ {getIcon(paused ? "resume" : "pause", paused ? "text-amber-400" : "text-foreground/60")}

- {getIcon("restart", "text-white/60")}
+ {getIcon("restart", "text-foreground/60")}

- {getIcon("cancel", "text-white/60")}
+ {getIcon("cancel", "text-foreground/60")}

- {getIcon("videoFile", "text-white/60")}
+ {getIcon("videoFile", "text-foreground/60")}

- {getIcon("folder", "text-white/60")}
+ {getIcon("folder", "text-foreground/60")}
- className={`h-8 w-8 rounded-lg border border-white/10 bg-white/5 text-white/85 shadow-none transition-colors hover:bg-white/10 ${styles.electronNoDrag}`}
+ className={`h-8 w-8 rounded-lg border border-input bg-background/70 text-foreground/85 shadow-none transition-colors hover:bg-accent ${styles.electronNoDrag}`}

- <Languages size={13} className="text-white/75" />
+ <Languages size={13} className="text-foreground/75" />
- {loc === locale ? <Check size={11} className="text-white/85" /> : null}
+ {loc === locale ? <Check size={11} className="text-foreground/85" /> : null}

- {getIcon("minimize", "text-white")}
+ {getIcon("minimize")}

- {getIcon("close", "text-white")}
+ {getIcon("close")}

Also applies to: 546-612, 617-689

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/launch/LaunchWindow.tsx` around lines 67 - 75, Update the
hard-coded white text tokens so child icons inherit theme-aware colors: replace
instances of "text-white/55" and any other "text-white*" in
hudAuxIconBtnClasses, hudIconBtnClasses, and windowBtnClasses (and the similar
class blocks around lines 546-612 and 617-689) with the theme foreground token
(e.g., text-foreground or text-foreground/55) or remove explicit color to let
the parent class provide color; ensure hover/disabled styles still use
appropriate opacity but no longer force white so light/dark themes maintain
contrast.

@uunaign uunaign closed this by deleting the head repository Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants