@electerm/electerm-react 2.2.0 → 2.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/client/common/constants.js +1 -1
  2. package/client/common/ui-theme.js +25 -12
  3. package/client/components/ai/ai.styl +1 -3
  4. package/client/components/bg/custom-css.jsx +2 -2
  5. package/client/components/bookmark-form/common/serial-path-selector.jsx +1 -1
  6. package/client/components/common/highlight.styl +1 -2
  7. package/client/components/common/input-context-menu.jsx +294 -0
  8. package/client/components/common/opacity.jsx +66 -0
  9. package/client/components/file-transfer/transfer.styl +6 -9
  10. package/client/components/footer/footer.styl +2 -5
  11. package/client/components/layout/layout.styl +2 -3
  12. package/client/components/main/error-wrapper.jsx +3 -3
  13. package/client/components/main/main.jsx +4 -7
  14. package/client/components/main/term-fullscreen.styl +1 -1
  15. package/client/components/main/ui-theme.jsx +46 -6
  16. package/client/components/main/upgrade.styl +4 -6
  17. package/client/components/main/wrapper.styl +5 -27
  18. package/client/components/quick-commands/qm.styl +3 -6
  19. package/client/components/session/session.styl +11 -13
  20. package/client/components/setting-panel/list.styl +5 -5
  21. package/client/components/setting-panel/setting-wrap.styl +1 -6
  22. package/client/components/setting-panel/terminal-bg-config.jsx +3 -0
  23. package/client/components/setting-sync/setting-sync-form.jsx +0 -1
  24. package/client/components/sftp/file-item.jsx +3 -0
  25. package/client/components/sftp/sftp-entry.jsx +50 -9
  26. package/client/components/sftp/sftp.styl +21 -34
  27. package/client/components/sftp/transfer-tag.styl +3 -5
  28. package/client/components/side-panel-r/right-side-panel.styl +7 -9
  29. package/client/components/sidebar/info.styl +1 -14
  30. package/client/components/sidebar/sidebar.styl +16 -18
  31. package/client/components/sys-menu/sys-menu.styl +8 -11
  32. package/client/components/tabs/tabs.styl +34 -35
  33. package/client/components/terminal/term-search.styl +3 -3
  34. package/client/components/terminal/terminal-search-bar.jsx +1 -1
  35. package/client/components/terminal/terminal.jsx +2 -2
  36. package/client/components/terminal/terminal.styl +22 -27
  37. package/client/components/terminal-info/terminal-info.styl +8 -8
  38. package/client/components/theme/terminal-theme-list.styl +2 -2
  39. package/client/components/theme/theme-list-item.jsx +62 -20
  40. package/client/components/tree-list/tree-list.styl +1 -1
  41. package/client/css/basic.styl +6 -12
  42. package/client/css/includes/theme.styl +16 -0
  43. package/client/store/ui-theme.js +0 -35
  44. package/client/views/index.pug +8 -1
  45. package/package.json +1 -1
  46. package/client/components/common/native-input.styl +0 -7
  47. package/client/components/setting-sync/sync.styl +0 -7
  48. package/client/components/terminal/zmodem.styl +0 -14
  49. package/client/css/antd-overwrite.styl +0 -10
  50. package/client/css/includes/theme-default.styl +0 -20
@@ -1,13 +1,11 @@
1
- @require '../../css/includes/theme-default'
2
1
  .upgrade-panel
3
2
  position fixed
4
3
  right 10px
5
4
  bottom 10px
6
5
  z-index 9999
7
- background main
8
- color text
6
+ background var(--main)
9
7
  border-radius 5px
10
- border 1px solid darken(main, 30%)
8
+ border 1px solid var(--main-darker)
11
9
  padding 0
12
10
  width 440px
13
11
  .upgrade-panel-hide
@@ -17,12 +15,12 @@
17
15
  bottom auto
18
16
  .close-upgrade-panel
19
17
  &:hover
20
- color success
18
+ color var(--success)
21
19
  .upgrade-panel-title
22
20
  .upgrade-panel-body
23
21
  padding 10px 15px
24
22
  .upgrade-panel-title
25
- border-bottom 1px solid darken(main, 30%)
23
+ border-bottom 1px solid var(--main-darker)
26
24
  .markdown-wrap
27
25
  max-height 40vh
28
26
  overflow-y auto
@@ -1,4 +1,3 @@
1
- @require '../../css/includes/theme-default'
2
1
  .common-err-desc
3
2
  &:hover
4
3
  text-overflow clip
@@ -6,43 +5,22 @@
6
5
  white-space pre
7
6
  max-height 300px
8
7
  overflow scroll
9
- // .pinned .sessions
10
- // margin-left 343px
8
+
11
9
  .error-wrapper
12
- background main
10
+ background var(--main)
13
11
  height 100%
14
12
  position fixed
15
- color text
16
13
  overflow-y scroll
17
- .init-wrap
18
- .loading-data
19
- position fixed
20
- left 0
21
- top 0
22
- width 100%
23
- height 100%
24
- background-color main-light
25
- .loading-data
26
- text-align center
27
- font-size 30px
28
- color text
29
- padding 50px
30
- z-index 210
31
- .ant-tag
32
- border-radius 3px
33
- padding 4px
34
- font-size 14px
35
- .loaded
36
- .loading-data
37
- display none
38
14
 
39
15
  #container
16
+ .xterm
17
+ padding 10px
40
18
  .session-batch-active
41
19
  .xterm-screen
42
20
  &::before
43
21
  font-size 30vmin
44
22
  font-weight bold
45
- color alpha(text, 0.15)
23
+ color var(--text)
46
24
  display flex
47
25
  justify-content center
48
26
  align-items center
@@ -1,13 +1,11 @@
1
- @require '../../css/includes/theme-default'
2
1
  .qm-list-wrap
3
2
  max-height calc(100vh - 100px)
4
3
  overflow-y scroll
5
4
  .qm-wrap-tooltip
6
- background main
5
+ background var(--main)
7
6
  position absolute
8
7
  left 43px
9
8
  right 0
10
- color text
11
9
  z-index 89
12
10
  height auto
13
11
  bottom 36px
@@ -21,15 +19,14 @@
21
19
  .fil-keyword
22
20
  .fil-label
23
21
  .qm-item
24
- opacity .4
22
+ color var(--text-light)
25
23
  .qm-item
26
24
  &.name-match
27
25
  &.label-match
28
26
  font-weight bold
29
- opacity 1
30
27
  @media (max-width: 500px)
31
28
  .qm-search-input
32
29
  width 100px
33
30
 
34
31
  .item-list-unit.dragover
35
- border: 1px dashed primary
32
+ border: 1px dashed var(--primary)
@@ -1,4 +1,3 @@
1
- @require '../../css/includes/theme-default'
2
1
  @keyframes rotate
3
2
  from
4
3
  background-position -3000px
@@ -10,7 +9,7 @@
10
9
  left 0
11
10
  width 100%
12
11
  height 1px
13
- background text-dark
12
+ background var(--text-dark)
14
13
  display none
15
14
  .type-tab-txt
16
15
  position relative
@@ -20,14 +19,13 @@
20
19
  display inline-block
21
20
  vertical-align middle
22
21
  line-height 30px
23
- color text-dark
24
22
  padding 0 20px 0 0
25
23
  margin-right 0px
26
24
  font-size 14px
27
25
  cursor pointer
28
26
  &:hover
29
27
  &.active
30
- color text
28
+ color var(--text-light)
31
29
  &.active
32
30
  .type-tab-line
33
31
  display inline-block
@@ -36,34 +34,34 @@
36
34
  .type-tab.sftp
37
35
  .type-tab-line
38
36
  display inline-block
39
- background linear-gradient(to right, success 0%, main 25%, error 50%, primary 75%, success 100%)
37
+ background linear-gradient(to right, var(--success) 0%, var(--main) 25%, var(--error) 50%, var(--primary) 75%, var(--success) 100%)
40
38
  animation: rotate 60s infinite linear
41
39
  .disable-ssh
42
40
  .type-tab.ssh
43
41
  display none
44
42
  .spliter
45
- color text
43
+ color var(--text)
46
44
  &:hover
47
- color text-light
45
+ color var(--text-light)
48
46
 
49
47
  .sessions
50
48
  position absolute
51
- background main
49
+ background var(--main)
52
50
  .session-wrap
53
51
  display none
54
52
  position absolute
55
53
  overflow hidden
56
54
  z-index 3
57
55
  padding-top 36px
58
- box-shadow 0px 0px 1px 1px alpha(main, .3)
56
+ box-shadow 0px 0px 1px 1px var(--main-darker)
59
57
  &.session-batch-active
60
58
  display block
61
59
 
62
60
  .web-session-wrap
63
61
  height 100vh
64
- background main
62
+ background var(--main)
65
63
  .session-v-wrap
66
- background main
64
+ background var(--main)
67
65
  overflow scroll
68
66
  z-index 99
69
67
  .vnc-session-wrap > div
@@ -76,8 +74,8 @@
76
74
  .sess-icon
77
75
  margin-right 10px
78
76
  &.active
79
- color warn
77
+ color var(--warn)
80
78
 
81
79
  .split-view-toggle
82
80
  &.active
83
- color success
81
+ color var(--success)
@@ -1,4 +1,4 @@
1
- @require '../../css/includes/theme-default'
1
+
2
2
  .item-list-wrap
3
3
  overflow-y scroll
4
4
  &::-webkit-scrollbar
@@ -22,13 +22,13 @@
22
22
  cursor pointer
23
23
  line-height 1.8
24
24
  &.active
25
- background primary
26
- color contrastColor(primary)
25
+ background var(--primary)
26
+ color var(--primary-contrast)
27
27
  &.current
28
28
  font-weight bold
29
29
  &:hover
30
- background darken(primary, 30%)
31
- color contrastColor(darken(primary, 30%))
30
+ background var(--primary)
31
+ color var(--primary-contrast)
32
32
  .list-item-apply
33
33
  .list-item-edit
34
34
  .list-item-remove
@@ -1,7 +1,3 @@
1
- @require '../../css/includes/theme-default'
2
-
3
- .setting-wrap
4
- color text
5
1
 
6
2
  body .ant-drawer .ant-drawer-content-wrapper
7
3
  left 43px
@@ -9,11 +5,10 @@ body .ant-drawer .ant-drawer-content-wrapper
9
5
  position absolute
10
6
  top 70px
11
7
  font-size 16px
12
- color text
13
8
  cursor pointer
14
9
  z-index 889
15
10
  &:hover
16
- color text
11
+ color var(--success)
17
12
  .alt-close-setting-wrap
18
13
  right 20px
19
14
  .close-setting-wrap
@@ -23,6 +23,9 @@ export default function TerminalBackgroundConfig ({
23
23
  isGlobal = false,
24
24
  batchUpdate
25
25
  }) {
26
+ if (!config) {
27
+ return null
28
+ }
26
29
  const [showTextModal, setShowTextModal] = useState(false)
27
30
  const value = config[name]
28
31
  const defaultValue = defaultSettings[name]
@@ -12,7 +12,6 @@ import Link from '../common/external-link'
12
12
  import dayjs from 'dayjs'
13
13
  import eq from 'fast-deep-equal'
14
14
  import { syncTokenCreateUrls, syncTypes } from '../../common/constants'
15
- import './sync.styl'
16
15
  import HelpIcon from '../common/help-icon'
17
16
  import ServerDataStatus from './server-data-status'
18
17
  import Password from '../common/password'
@@ -872,6 +872,9 @@ export default class FileSection extends React.Component {
872
872
  }
873
873
 
874
874
  handleContextMenuCapture = (e) => {
875
+ if (!this.isSelected(this.state.file)) {
876
+ this.onClick(e)
877
+ }
875
878
  this.contextMenuPosition = {
876
879
  clientY: e.clientY
877
880
  }
@@ -27,7 +27,7 @@ import fs from '../../common/fs'
27
27
  import ListTable from './list-table-ui'
28
28
  import deepCopy from 'json-deep-copy'
29
29
  import isValidPath from '../../common/is-valid-path'
30
- import memoizeOne from 'memoize-one'
30
+
31
31
  import * as owner from './owner-list'
32
32
  import AddressBar from './address-bar'
33
33
  import getProxy from '../../common/get-proxy'
@@ -101,6 +101,9 @@ export default class Sftp extends Component {
101
101
  this.timer4 = null
102
102
  clearTimeout(this.timer5)
103
103
  this.timer5 = null
104
+ // Clear sort cache to prevent memory leaks
105
+ this._sortCache?.clear()
106
+ this._lastSortArgs = null
104
107
  }
105
108
 
106
109
  initFtpData = async () => {
@@ -167,19 +170,36 @@ export default class Sftp extends Component {
167
170
  }, {})
168
171
  }
169
172
 
170
- sort = memoizeOne((
171
- list,
172
- type,
173
- sortDirection,
174
- sortProp
175
- ) => {
173
+ // Cache for memoized sort results
174
+ _sortCache = new Map()
175
+ _lastSortArgs = null
176
+
177
+ sort = (list, type, sortDirection, sortProp) => {
178
+ // Create a cache key from the arguments
179
+ const cacheKey = JSON.stringify({
180
+ listLength: list?.length || 0,
181
+ listHash: this._hashList(list),
182
+ type,
183
+ sortDirection,
184
+ sortProp
185
+ })
186
+
187
+ // Check if we have a cached result and if args haven't changed
188
+ if (this._lastSortArgs && isEqual(this._lastSortArgs, [list, type, sortDirection, sortProp])) {
189
+ const cached = this._sortCache.get(cacheKey)
190
+ if (cached) {
191
+ return cached
192
+ }
193
+ }
194
+
195
+ // Compute the result
176
196
  if (!list || !list.length) {
177
197
  return []
178
198
  }
179
199
 
180
200
  const isDesc = sortDirection === 'desc'
181
201
 
182
- return list.slice().sort((a, b) => {
202
+ const result = list.slice().sort((a, b) => {
183
203
  // Handle items with no id first
184
204
  if (!a.id && b.id) return -1
185
205
  if (a.id && !b.id) return 1
@@ -207,7 +227,28 @@ export default class Sftp extends Component {
207
227
  if (aValue > bValue) return isDesc ? -1 : 1
208
228
  return 0
209
229
  })
210
- }, isEqual)
230
+
231
+ // Cache the result
232
+ this._lastSortArgs = [list, type, sortDirection, sortProp]
233
+ this._sortCache.set(cacheKey, result)
234
+
235
+ // Limit cache size to prevent memory leaks
236
+ if (this._sortCache.size > 10) {
237
+ const firstKey = this._sortCache.keys().next().value
238
+ this._sortCache.delete(firstKey)
239
+ }
240
+
241
+ return result
242
+ }
243
+
244
+ // Helper method to create a simple hash of the list for cache key
245
+ _hashList = (list) => {
246
+ if (!list || !list.length) return 0
247
+ return list.reduce((hash, item, index) => {
248
+ const str = `${item.id || ''}${item.name || ''}${item.modifyTime || ''}${index}`
249
+ return hash + str.length
250
+ }, 0)
251
+ }
211
252
 
212
253
  isActive () {
213
254
  const { currentBatchTabId, pane, sshSftpSplitView } = this.props
@@ -1,5 +1,3 @@
1
- @require '../../css/includes/theme-default'
2
-
3
1
  .sftp-wrap
4
2
  display flex
5
3
  flex-direction row
@@ -17,15 +15,15 @@
17
15
  margin-bottom 4px
18
16
  &:nth-child(even)
19
17
  .sftp-file-prop
20
- background main
18
+ background var(--main)
21
19
  &:hover
22
20
  .sftp-file-prop
23
- background-color primary
24
- color contrastColor(primary)
21
+ background-color var(--primary)
22
+ color var(--primary-contrast)
25
23
  &.selected
26
24
  .sftp-file-prop
27
- background-color darken(primary, 30%)
28
- color contrastColor(primary)
25
+ background-color var(--primary)
26
+ color var(--primary-contrast)
29
27
  .sftp-history
30
28
  position absolute
31
29
  left 0
@@ -40,15 +38,15 @@
40
38
  border-radius 3px
41
39
  &.focused
42
40
  height auto
43
- border 1px solid main-dark
44
- box-shadow 0px 0px 3px 3px alpha(main, .05)
41
+ border 1px solid var(--main-darker)
42
+ box-shadow 0px 0px 3px 3px var(--main-lighter)
45
43
 
46
44
  .sftp-history-item
47
45
  padding 5px 10px
48
46
  cursor pointer
49
- border-bottom 1px solid primary
47
+ border-bottom 1px solid var(--main-darker)
50
48
  &:hover
51
- background main-dark
49
+ background var(--main-darker)
52
50
 
53
51
  .sftp-item-title
54
52
  width 100%
@@ -57,11 +55,11 @@
57
55
  .sftp-item-size
58
56
  width 24%
59
57
  .sftp-status-success
60
- color success
58
+ color var(--success)
61
59
  .sftp-status-exception
62
- color error
60
+ color var(--error)
63
61
  .sftp-status-active
64
- color primary
62
+ color var(--primary)
65
63
 
66
64
  .virtual-file
67
65
  .sftp-item
@@ -72,7 +70,6 @@
72
70
  top 0
73
71
  z-index 1
74
72
  height 100%
75
- opacity 0
76
73
  padding 0
77
74
  margin 0
78
75
 
@@ -86,19 +83,11 @@
86
83
  width 100%
87
84
  .file-props
88
85
  margin-left 70px
89
- .opacity-loop
90
- opacity 0.3
91
- animation blinker 5s linear infinite
92
-
93
- @keyframes blinker
94
- 50%
95
- opacity .8
96
86
 
97
87
  .sftp-sort-btn
98
- color text
99
88
  &.active
100
89
  font-weight bold
101
- color text-light
90
+ color var(--text-light)
102
91
 
103
92
  //list table
104
93
  .sftp-file-prop
@@ -106,13 +95,13 @@
106
95
  height 32px
107
96
  line-height 30px
108
97
  padding 0 5px
109
- background main
98
+ background var(--main)
110
99
  overflow hidden
111
100
  white-space nowrap
112
101
  text-overflow ellipsis
113
102
  pointer-events none
114
103
  cursor default
115
- color text
104
+ color var(--text)
116
105
 
117
106
  .file-bg
118
107
  position absolute
@@ -130,7 +119,6 @@
130
119
  overflow hidden
131
120
  white-space nowrap
132
121
  text-overflow ellipsis
133
- color text
134
122
 
135
123
  .sftp-file-table-header
136
124
  height 30px
@@ -142,8 +130,8 @@
142
130
  .sftp-item
143
131
  &.sftp-dragover
144
132
  .sftp-file-prop
145
- background primary !important
146
- color text-light !important
133
+ background var(--primary) !important
134
+ color var(--text) !important
147
135
  &.sftp-dragover-multi
148
136
  &:after
149
137
  &:before
@@ -152,7 +140,7 @@
152
140
  top 2px
153
141
  width 100%
154
142
  height 100%
155
- background main-light
143
+ background var(--main-lighter)
156
144
  content ''
157
145
  z-index -1
158
146
  &:after
@@ -166,12 +154,11 @@
166
154
 
167
155
  //sftp
168
156
  .sftp-panel
169
- background main
170
- color text
157
+ background var(--main)
171
158
 
172
159
  .file-list
173
160
  ::-webkit-scrollbar-thumb
174
- background-color primary !important
161
+ background-color var(--primary) !important
175
162
 
176
163
  .pager-wrap
177
164
  z-index 4
@@ -183,4 +170,4 @@
183
170
  .keyword-filter-icon
184
171
  &:hover
185
172
  &.active
186
- color success
173
+ color var(--success)
@@ -1,11 +1,9 @@
1
- @require '../../css/includes/theme-default'
2
1
  .transfer-tag
3
- color text
4
2
  border-radius 2px
5
3
  padding 0 2px
6
4
  .transfer-status-init
7
- color primary
5
+ color var(--primary)
8
6
  .transfer-status-started
9
- color success
7
+ color var(--success)
10
8
  .transfer-status-error
11
- color error
9
+ color var(--error)
@@ -1,14 +1,12 @@
1
- @require '../../css/includes/theme-default'
2
-
3
1
  .right-side-panel
4
2
  position absolute
5
3
  right 0
6
4
  top 36px
7
5
  bottom 0
8
6
  z-index 200
9
- background main
10
- color text-light
11
- border-left 1px solid darken(main, 30%)
7
+ background var(--main)
8
+ color var(--text)
9
+ border-left 1px solid var(--main-darker)
12
10
  &.right-side-panel-pinned
13
11
  top 0
14
12
 
@@ -17,16 +15,16 @@
17
15
  right auto
18
16
  display block
19
17
  .right-panel-title
20
- border-bottom 1px solid darken(main, 30%)
18
+ border-bottom 1px solid var(--main-darker)
21
19
  .right-side-panel-controls
22
- color text-dark
20
+ color var(--text)
23
21
  font-size 16px
24
22
  &:hover
25
- color text
23
+ color var(--success)
26
24
  cursor pointer
27
25
  &.right-side-panel-pin
28
26
  &.pinned
29
- color success
27
+ color var(--success)
30
28
  .right-side-panel-content
31
29
  padding 10px
32
30
  overflow-y scroll
@@ -1,24 +1,11 @@
1
- @require '../../css/includes/theme-default'
2
1
 
3
2
  // from https://freefrontend.com/css-border-animations/
4
3
  .morph-shape
5
- background linear-gradient(45deg, primary 0%, success 100%)
6
- animation morph 8s ease-in-out infinite
4
+ background linear-gradient(45deg, #08c 0%, #09c 100%)
7
5
  border-radius 60% 40% 30% 70% / 60% 30% 70% 40%
8
6
  transition all 1s ease-in-out
9
7
  z-index 5
10
8
 
11
- @keyframes morph
12
- 0%
13
- border-radius 60% 40% 30% 70% / 60% 30% 70% 40%
14
- background linear-gradient(45deg, primary 0%, success 100%)
15
- 50%
16
- border-radius 30% 60% 70% 40% / 50% 60% 30% 60%
17
- background linear-gradient(45deg, main 0%, success 100%)
18
-
19
- 100%
20
- border-radius 60% 40% 30% 70% / 60% 30% 70% 40%
21
- background linear-gradient(45deg, primary 0%, success 100%)
22
9
  .info-modal
23
10
  .ant-modal-header
24
11
  border none
@@ -1,4 +1,4 @@
1
- @require '../../css/includes/theme-default'
1
+
2
2
  .animate-fast
3
3
  animation-duration .2s
4
4
  .sidebar-panel
@@ -9,8 +9,7 @@
9
9
  z-index 200
10
10
  width 0
11
11
  overflow-y scroll
12
- background main
13
- color text
12
+ background var(--main)
14
13
  .item-list-unit:hover
15
14
  .list-item-remove
16
15
  display none !important
@@ -22,8 +21,8 @@
22
21
  width 36px
23
22
  z-index 100
24
23
  bottom 0
25
- background main-dark
26
- box-shadow 0px 0px 3px 3px alpha(main, .1)
24
+ background var(--main-darker)
25
+
27
26
  .item-list
28
27
  padding-right 0
29
28
  .sidebar-pin-top
@@ -52,20 +51,20 @@
52
51
  .history-panel
53
52
  width 100%
54
53
  .control-icon-text
55
- color text
54
+ color var(--text)
56
55
  &:hover
57
- color text-light
56
+ color var(--success)
58
57
  .control-icon-wrap
59
58
  padding 14px 0
60
59
  text-align center
61
60
  &.active
62
61
  .control-icon
63
- color text-light
62
+ color var(--text-light)
64
63
  .control-icon
65
- color text-dark
64
+ color var(--text-dark)
66
65
  cursor pointer
67
66
  &:hover
68
- color text-light
67
+ color var(--text-light)
69
68
  .sidebar-list
70
69
  position absolute
71
70
  left 43px
@@ -73,7 +72,6 @@
73
72
  bottom 0
74
73
  z-index 200
75
74
  width 0
76
- border-right 1px solid darken(main, 30%)
77
75
 
78
76
  .pinned
79
77
  .sidebar-list
@@ -85,22 +83,22 @@
85
83
  display block
86
84
  .sidebar-panel
87
85
  .pinned
88
- color success
86
+ color var(--success)
89
87
  //btns
90
88
  .btns
91
- background main-dark
92
- border-color primary
89
+ background var(--main-darker)
90
+ border-color var(--primary)
93
91
  .open-about-icon
94
- color text-dark
92
+ color var(--text-dark)
95
93
  &:hover
96
- color text-light
94
+ color var(--text-light)
97
95
 
98
96
  .btns .upgrade-icon
99
- color success
97
+ color var(--success)
100
98
  .close-info-modal
101
99
  cursor pointer
102
100
  &:hover
103
- color text-light
101
+ color var(--text-light)
104
102
  .logo-filter
105
103
  filter invert(80%)
106
104
  .sidebar-inner