Themeable selection color via --selection-bg, shared by page and CodeMirror
Nitro's orange accent selection fill clashed with accent-colored text. Introduce --selection-bg (base: accent 30% mix, as before) used by both ::selection and the editors' selection layer; nitro overrides it with a neutral grey. CodeMirror's selection needed a baseTheme with its exact &light/&dark selectors to win, and is now hidden when unfocused like a normal input.
This commit is contained in:
@@ -18,6 +18,9 @@
|
|||||||
/* Links stay quiet — mostly text color with a hint of the accent —
|
/* Links stay quiet — mostly text color with a hint of the accent —
|
||||||
and light up to the full accent on hover. */
|
and light up to the full accent on hover. */
|
||||||
--link: color-mix(in oklab, var(--text) 50%, var(--accent));
|
--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
|
/* Code highlighting palette, consumed by pygments.css: complete light and
|
||||||
dark sets (background included), resolved by light-dark() from the
|
dark sets (background included), resolved by light-dark() from the
|
||||||
used color-scheme. A theme picks a set simply by declaring
|
used color-scheme. A theme picks a set simply by declaring
|
||||||
@@ -71,7 +74,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
::selection {
|
::selection {
|
||||||
background: color-mix(var(--accent) 30%, transparent);
|
background: var(--selection-bg);
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-3
@@ -8,7 +8,7 @@ import { tags } from '@lezer/highlight'
|
|||||||
|
|
||||||
// The base theme sets monospace on .cm-scroller, so the font must be set
|
// The base theme sets monospace on .cm-scroller, so the font must be set
|
||||||
// there, not on "&".
|
// there, not on "&".
|
||||||
export const cmTheme = EditorView.theme({
|
const cmEditorTheme = EditorView.theme({
|
||||||
"&": {
|
"&": {
|
||||||
backgroundColor: "var(--bg)",
|
backgroundColor: "var(--bg)",
|
||||||
color: "var(--text)",
|
color: "var(--text)",
|
||||||
@@ -33,11 +33,25 @@ export const cmTheme = EditorView.theme({
|
|||||||
".cm-cursor": { borderLeftColor: "var(--text)" },
|
".cm-cursor": { borderLeftColor: "var(--text)" },
|
||||||
// basicSetup's active-line highlight assumes a dark theme.
|
// basicSetup's active-line highlight assumes a dark theme.
|
||||||
".cm-activeLine": { backgroundColor: "transparent" },
|
".cm-activeLine": { backgroundColor: "transparent" },
|
||||||
"&.cm-focused .cm-selectionBackground, .cm-selectionBackground":
|
|
||||||
{ backgroundColor: "var(--line)" },
|
|
||||||
"&.cm-focused": { outline: "none" },
|
"&.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([
|
export const cmHighlight = syntaxHighlighting(HighlightStyle.define([
|
||||||
{ tag: tags.heading, fontWeight: "600", color: "var(--accent)" },
|
{ tag: tags.heading, fontWeight: "600", color: "var(--accent)" },
|
||||||
{ tag: tags.strong, fontWeight: "700" },
|
{ tag: tags.strong, fontWeight: "700" },
|
||||||
|
|||||||
@@ -42,6 +42,9 @@
|
|||||||
--font-body: var(--font-montserrat);
|
--font-body: var(--font-montserrat);
|
||||||
--font-heading: var(--font-literata);
|
--font-heading: var(--font-literata);
|
||||||
--code-x-height: 0.517; /* Montserrat's x-height ratio */
|
--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
|
/* 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 */
|
/* Any banner used is separated from page by a thick orange line */
|
||||||
#banner {
|
#banner {
|
||||||
border-bottom: 4px solid var(--accent);
|
border-bottom: 4px solid var(--accent);
|
||||||
|
|||||||
Reference in New Issue
Block a user