Skip to content

Conversation

dpvc
Copy link
Member

@dpvc dpvc commented Oct 19, 2025

This PR adds support for dork-mode. Most of the changes are to add @media CSS queries to override styles that use colors to provide dark-mode versions. But there are a few more detailed changes.

In complexity/collapse.ts, we don't set mathcolor: blue, since that isn't able to be adjusted for dark mode. Instead, we use CSS to add the color in the CHTML and SVG maction.ts files based on the data attributes.

The a11y/explorer/Highlighter.ts file has some significant changes. Because dark mode inverts the use of black and white for foreground and background, the black and white selections in the menu need to be able to be reassigned in dark mode. Also, the blue background (the default) doesn't work well in bark mode, as it is too dark. So we need a slightly altered background blue in dark mode. In order to handle these color changes, we create CSS variables that hold the color values and have the highlighter refer to them rather than set the RGB values directly. That way we will get the correct values for the light/dark mode automatically (and even if the user changes while the explorer is running, everything will work properly).

That means we don't need the ChannelColor or namedColor objects, as these are moved into the CSS directly. The getColorString() function is modified to refer to the CSS variables rather thanscetting the values directly. The alpha values in dark-mode need to be a bit larger (at least for the blue background), so the dark and light alpha values differ and are stored in CSS variables so that the right one is used automatically. Because the foreground and background blue values also differ from each other in dark mode, we use separate color variables for foreground and background in order to accommodate that difference. To a type value is added to the NamedColor interface and the default colors include that in order to distinguish which kind is being used.

The a11y/explorer/Region.ts file now checks for the presence of the stylesheet rather than using a global variable (so that this can be used with multiple documents (like iframe or shadow DOM). An id attribute is added to the style sheet to make that possible. The color CSS variables are added to the LiveRegion CSS, since that is used by both the speech and Braille regions. The SpeechRegion sets its style value to null so that duplicate CSS isn't introduced (it inherits the LiveRegion styles).

The :root CSS rules are first in the list so that they can be found easily in order to adjust the alpha variables when the opacity values are changed in the contextual menu. Because the other CSS styles come after, the color values used in them are set in CSS variables as well (otherwise the later values would override the ones set in the @media query. Though it would be possible to have added a second one after the other definitions, it seemed easier to use variables in this case. (That could have been done throughout, but there would be a lot of variables. It would make things more semantic, I suppose, so I could consider that if you thought it was worth doing.)

A new setAlpha() function is added to the LiveRegion class in order to adjust the CSS variables for the foreground and background colors. The dark-mode alpha uses a power of 1/sqrt(2) to cause it to be larger than the light-mode alpha, in particular to allow the blue background to be visible at the default 20% opacity (this makes it about 32% instead), while still having 0% and 100% be correct. I think this works out pretty well, even with the flame highlighting, but we can change the formula if that doesn't work out for you.

This LiveRegion.setAlpha() method gets called by the menu code from a new setAlpha() menu method that is called when the menu sliders are changed.

The maction.ts files are modified to give dark colors for tooltips and status-line actions, and to set the blue color for the collapsed expressions (lighter blue for dark mode).

Finally, the util/StyleJson.ts file is adjusted to allow StyleJson to have the nested styles needed for the @media queries. The getStyleRules() method is now recursive to make that possible.

I think this covers all the UI that has colors that need to be made dark. If you find anything else, let me know.

@dpvc dpvc requested a review from zorkow October 19, 2025 20:29
@dpvc dpvc added this to the v4.0.1 milestone Oct 19, 2025
@dpvc
Copy link
Member Author

dpvc commented Oct 19, 2025

PS, you may want to apply the dark-mode PR in the context-menu repository as well to see how they work together. I'm also going to make a PR in the dev repository for the dark-mode support in the lab.

@dpvc dpvc force-pushed the feature/dark-mode branch from 0ec4a0d to 2df9977 Compare October 20, 2025 12:46
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.

1 participant