diff --git a/CHANGELOG.md b/CHANGELOG.md
index 56cc84e..d3ef5c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,11 @@ To see every change with descriptions aimed at developers, see
As a continuously updated web app, Cocreate uses dates
instead of version numbers.
+## 2023-04-08
+
+* Dark mode better preserves color saturation using new SVG color filter
+ from [Dark Reader](https://darkreader.org/)'s Filter+ mode.
+
## 2023-01-20
* Fix SVG export of pen strokes with arrows.
diff --git a/client/DrawApp.coffee b/client/DrawApp.coffee
index 7a2443f..f988eb0 100644
--- a/client/DrawApp.coffee
+++ b/client/DrawApp.coffee
@@ -485,6 +485,12 @@ export DrawAppRoom = ->
+ {### Filter+ from Dark Reader, https://github.com/darkreader/darkreader/blob/7f047b20909b09b8cdb3e45550d0c586abeb98a4/src/generators/utils/matrix.ts#L42 ###}
+
+
+
{### arrowhead from https://developer.mozilla.org/en-US/docs/Web/SVG/Element/marker ###}
if fancyCursor.get()
options = {}
if dark.get()
- options.style = 'filter:invert(1) hue-rotate(180deg)'
+ #options.style = 'filter:invert(1) hue-rotate(180deg)'
+ options.style = 'filter:url(#invertFilter)'
icons.cursorCSS icon, xFrac, yFrac, options
else
null
diff --git a/client/lib/icons.coffee b/client/lib/icons.coffee
index 974a7b7..8e0cd54 100644
--- a/client/lib/icons.coffee
+++ b/client/lib/icons.coffee
@@ -156,10 +156,15 @@ export modIcon = (icon, attrs) ->
icon
## Wrap icon in tag
+invertFilter = null
export svgIcon = (icon, attrs) ->
icon = getIcon icon
if typeof icon == 'object'
{icon, width} = icon
+ ## Include inverting if needed
+ if attrs?.style?.includes 'invertFilter'
+ invertFilter ?= document.getElementById('invertFilter').outerHTML
+ icon = invertFilter + icon
""""""
## Stack icons, from bottom to top, just by concatenation
diff --git a/client/main.styl b/client/main.styl
index b3a57b0..a220b36 100644
--- a/client/main.styl
+++ b/client/main.styl
@@ -95,13 +95,18 @@ html, body, #root, #container
grid-area: center
position: relative
+body
+ --filter: none
+ &.dark
+ //--filter: invert(1) hue-rotate(180deg)
+ --filter: url(#invertFilter)
+
.board, .modal, .overlay
position: absolute
overflow: hidden
width: 100%
height: 100%
- /.dark &
- filter: invert(1) hue-rotate(180deg)
+ filter: var(--filter)
.board
cursor: crosshair
touch-action: none // PointerEvents only
@@ -224,8 +229,8 @@ button(activeBorder)
fill: black
text-anchor: middle
font-size: 10px
- /.dark & svg
- filter: invert(1) hue-rotate(180deg)
+ svg
+ filter: var(--filter)
.width, .dash
line
stroke: var(--currentColor)
@@ -233,8 +238,7 @@ button(activeBorder)
.color, .opacity, [data-tool="fill"] svg
width: 100%
height: 100%
- /.dark &
- filter: invert(1) hue-rotate(180deg)
+ filter: var(--filter)
#opacities > .tool:not(:first-child)
padding: 0
@@ -440,7 +444,7 @@ body:not(.history)
.modal.error
background: pink
.modal.info
- background: #bbb
+ background: #ddd
.modal-title
font-weight: bold
font-size: larger
@@ -460,8 +464,7 @@ body:not(.history)
svg
width: 100%
max-height: 50vh
- /.dark &
- filter: invert(1) hue-rotate(180deg)
+ filter: var(--filter)
// Based on keyframes from Font Awesome Free (see `lib/icons.coffee`).
@keyframes fa-spin