diff --git a/frontend/src/assets/pagerite.css b/frontend/src/assets/pagerite.css index 0a94b18..f69599b 100644 --- a/frontend/src/assets/pagerite.css +++ b/frontend/src/assets/pagerite.css @@ -18,6 +18,9 @@ /* Links stay quiet — mostly text color with a hint of the accent — and light up to the full accent on hover. */ --link: color-mix(in oklab, var(--text) 50%, var(--accent)); + /* Selection fill for page text and the CodeMirror editors; themes + override when the accent tint clashes with accent-colored text. */ + --selection-bg: color-mix(var(--accent) 30%, transparent); /* Code highlighting palette, consumed by pygments.css: complete light and dark sets (background included), resolved by light-dark() from the used color-scheme. A theme picks a set simply by declaring @@ -71,7 +74,7 @@ } ::selection { - background: color-mix(var(--accent) 30%, transparent); + background: var(--selection-bg); color: inherit; } diff --git a/frontend/src/cmtheme.js b/frontend/src/cmtheme.js index 5561d41..72c7f88 100644 --- a/frontend/src/cmtheme.js +++ b/frontend/src/cmtheme.js @@ -8,7 +8,7 @@ import { tags } from '@lezer/highlight' // The base theme sets monospace on .cm-scroller, so the font must be set // there, not on "&". -export const cmTheme = EditorView.theme({ +const cmEditorTheme = EditorView.theme({ "&": { backgroundColor: "var(--bg)", color: "var(--text)", @@ -33,11 +33,25 @@ export const cmTheme = EditorView.theme({ ".cm-cursor": { borderLeftColor: "var(--text)" }, // basicSetup's active-line highlight assumes a dark theme. ".cm-activeLine": { backgroundColor: "transparent" }, - "&.cm-focused .cm-selectionBackground, .cm-selectionBackground": - { backgroundColor: "var(--line)" }, "&.cm-focused": { outline: "none" }, }) +// Selection color needs a baseTheme: only base themes support the +// &light/&dark selectors, and @codemirror/view's own selection rules use +// them — we must match its selectors exactly (equal specificity) and rely +// on mounting later to win. Focused: the page's --selection-bg (the base +// accents tint; themes may override it). Unfocused: hidden, like a normal +// input (CodeMirror greys it by default). +const cmSelection = EditorView.baseTheme({ + "&light .cm-selectionBackground, &dark .cm-selectionBackground": + { backgroundColor: "transparent" }, + "&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, &dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": + { backgroundColor: "var(--selection-bg)" }, +}) + +// Exported as one extension so the editors just list `cmTheme`. +export const cmTheme = [cmEditorTheme, cmSelection] + export const cmHighlight = syntaxHighlighting(HighlightStyle.define([ { tag: tags.heading, fontWeight: "600", color: "var(--accent)" }, { tag: tags.strong, fontWeight: "700" }, diff --git a/pagerite/themes/nitro/theme.css b/pagerite/themes/nitro/theme.css index 1c5f8d2..0a5f3c4 100644 --- a/pagerite/themes/nitro/theme.css +++ b/pagerite/themes/nitro/theme.css @@ -42,6 +42,9 @@ --font-body: var(--font-montserrat); --font-heading: var(--font-literata); --code-x-height: 0.517; /* Montserrat's x-height ratio */ + /* Neutral grey selection instead of the accent tint: accent-colored + text (h2, links, markers) stays readable on it in both schemes. */ + --selection-bg: #6664; } /* Dark scheme: same identity, but the page goes deep violet (never muddy @@ -62,10 +65,6 @@ } } -::selection { - background: var(--accent); -} - /* Any banner used is separated from page by a thick orange line */ #banner { border-bottom: 4px solid var(--accent);