diff --git a/src/shared/versions.js b/src/shared/versions.js
index 35fd898..f26102a 100644
--- a/src/shared/versions.js
+++ b/src/shared/versions.js
@@ -1,6 +1,6 @@
export const HARBOR_VERSIONS = Object.freeze({
- macClient: '0.6.9',
- gatewayClient: '0.6.8',
+ macClient: '0.6.10',
+ gatewayClient: '0.6.9',
gatewayBackend: '0.6.0',
});
diff --git a/src/web/components/ClientOverviewPage.jsx b/src/web/components/ClientOverviewPage.jsx
index 612c228..5fcf507 100644
--- a/src/web/components/ClientOverviewPage.jsx
+++ b/src/web/components/ClientOverviewPage.jsx
@@ -402,7 +402,8 @@ function LocalRulesPanel({
>
.client-local-rule-enabled {
+ z-index: 101;
+ color: oklch(0.68 0.15 28);
+}
+
.client-local-rule-enabled {
width: 24px;
height: 32px;
@@ -1020,11 +1028,19 @@ p {
transition: fill 320ms ease, stroke 260ms ease;
}
-.client-local-rule-enabled path {
+.client-rule-check {
stroke-width: 1.8;
stroke-dasharray: 12;
stroke-dashoffset: 12;
- transition: stroke-dashoffset 360ms cubic-bezier(0.16, 1, 0.3, 1);
+ transition: opacity 160ms ease, stroke-dashoffset 360ms cubic-bezier(0.16, 1, 0.3, 1);
+}
+
+.client-rule-delete-cross {
+ stroke-width: 1.6;
+ opacity: 0;
+ transform: rotate(-35deg) scale(0.55);
+ transform-origin: center;
+ transition: opacity 160ms ease, transform 240ms cubic-bezier(0.16, 1, 0.3, 1);
}
.client-local-rule-enabled[aria-checked='true'] {
@@ -1040,10 +1056,21 @@ p {
fill: color-mix(in oklch, var(--client-accent) 12%, transparent);
}
-.client-local-rule-enabled[aria-checked='true'] path {
+.client-local-rule-enabled[aria-checked='true'] .client-rule-check {
stroke-dashoffset: 0;
}
+.client-deletable-row.is-removing .client-local-rule-enabled circle,
+.client-deletable-row.is-removing .client-rule-check {
+ opacity: 0;
+}
+
+.client-deletable-row.is-removing .client-rule-delete-cross {
+ opacity: 1;
+ transform: rotate(0) scale(1);
+ filter: drop-shadow(0 0 3px oklch(0.68 0.15 28 / 0.55));
+}
+
.client-rule-type {
position: relative;
min-width: 0;
diff --git a/test/web/rule-editor-contract.test.js b/test/web/rule-editor-contract.test.js
index 2846b4c..805fd14 100644
--- a/test/web/rule-editor-contract.test.js
+++ b/test/web/rule-editor-contract.test.js
@@ -21,10 +21,12 @@ test('rule editor add latency stays constant and dirty exits are guarded', () =>
assert.match(component, /Перезапустить VPN/);
assert.match(component, /client-deletable-row/);
assert.match(component, /className="client-delete-strike"[\s\S]*onAnimationEnd/);
+ assert.match(component, /client-rule-delete-cross/);
assert.match(styles, /\.client-deletable-row\.is-removing > \.client-delete-strike[\s\S]*client-delete-strike/);
- assert.match(styles, /\.client-delete-strike::after[\s\S]*clip-path: polygon\(0 50%[\s\S]*100% 50%/);
- assert.match(styles, /\.client-delete-strike \{[\s\S]*z-index: 100[\s\S]*radial-gradient/);
+ assert.match(styles, /\.client-delete-strike \{[\s\S]*z-index: 100[\s\S]*linear-gradient/);
assert.match(styles, /\.client-deletable-row\.is-removing > :not\(\.client-delete-strike\)[\s\S]*z-index: 0/);
+ assert.match(styles, /\.client-deletable-row\.is-removing > \.client-local-rule-enabled[\s\S]*z-index: 101/);
+ assert.match(styles, /clip-path: polygon\(0 8%, 100% 50%, 0 92%\)/);
assert.match(styles, /@keyframes client-delete-strike[\s\S]*scaleX\(0\)[\s\S]*scaleX\(1\)/);
assert.match(styles, /\.client-local-rule:has\(\.client-rule-type\.is-open\)[\s\S]*z-index: 5/);
});