Repository navigation
Implement a Dark Mode Inspired by Obsidian - #13
Merged
Merged
Conversation
ThePyProgrammer
marked this pull request as ready for review
October 30, 2026 06:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Appearance
Choose Light, Dark, or System from the Theme selector at the bottom of the sidebar, or from Library settings → Appearance. The selector is also available when the sidebar is collapsed. System is the default and follows changes to your device's appearance.
Dark mode uses Obsidian-inspired charcoal surfaces, subtle gray borders, muted text, and violet accents. The theme applies to navigation, library and project views, tables, forms, dialogs, Copilot, rich-text notes, canvases, graphs, charts, and LaTeX previews. Status colors and user-selected canvas/task colors retain their meaning.
Your preference is saved for this browser and synchronized between open tabs. It applies before the application loads to avoid a light flash. If browser storage is blocked, switching themes still works for the current session. Switching does not reload the page or change your notes.
Images, PDFs, and external embedded pages keep their original appearance. Printable note exports retain their print styling; canvas PNG exports use the current theme. JSON Canvas files store document data, not the application theme.
Development
frontend/themePalette.cjsgenerates the light and dark CSS variables used by Tailwind. Foreground, background, and border colors have separate roles, so utility variants such ashover:bg-slate-50and opacity modifiers work in either theme. Light mode retains the existing utility colors. The dark sidebar has its own surface scope for translucent white hover states.The stylesheet explicitly references
tailwind.config.cjs. Both the config and palette use CommonJS so Tailwind 3 can invalidate its configuration cache during development, including on Node versions with nativerequire(ESM)support. Native ES module caching can otherwise leave a running server serving the old light utilities after a config edit.Use Tailwind utilities or the
--ui-*variables infrontend/src/index.cssfor new UI surfaces. Custom editors, SVG visualizations, and imperative autocomplete menus use the same tokens. Keep data colors separate from interface colors. Recharts tooltips and third-party editors need explicit themed styles.ThemeProvidermanages the preference and system changes.frontend/public/theme.jsis the small pre-render script; keep its preference key and resolution rules consistent with the provider.Validation: run
npm run test:run,npm run test:e2e -- theme.spec.js, andnpm run buildfromfrontend. The full unit suite assumesTZ=UTC. Theme browser tests cover persistence, system changes, cross-tab updates, collapsed navigation, application surfaces, dialogs, notes, graphs, and canvases, and produce screenshots for review.