Update VPN proxy client behavior
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
grid-column: 2;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
gap: 18px;
|
||||
gap: 12px;
|
||||
text-align: center;
|
||||
animation: client-power-arrive 850ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||
}
|
||||
@@ -36,6 +36,22 @@
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.client-power-section.is-gateway .client-power-control,
|
||||
.client-power-section.is-gateway .client-power {
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
|
||||
.client-power-section.is-gateway .client-power svg {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.client-power-section.is-gateway .client-power::before {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.client-power-control:focus-visible {
|
||||
outline: 1px solid color-mix(in oklch, var(--client-accent) 64%, transparent);
|
||||
outline-offset: 5px;
|
||||
@@ -188,7 +204,7 @@
|
||||
min-height: 44px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin-top: 8px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.client-state-detail > * {
|
||||
@@ -209,6 +225,10 @@
|
||||
transition: opacity 260ms ease, filter 420ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-power-section.is-gateway .client-duration {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.client-duration.is-active {
|
||||
opacity: 1;
|
||||
filter: blur(0);
|
||||
@@ -324,7 +344,7 @@
|
||||
justify-items: center;
|
||||
gap: 5px;
|
||||
width: 240px;
|
||||
margin-top: 6px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.client-proxies.is-gateway {
|
||||
|
||||
@@ -746,12 +746,27 @@
|
||||
stroke: var(--client-accent);
|
||||
}
|
||||
|
||||
.client-device-traffic-lines .is-download {
|
||||
stroke: var(--client-accent);
|
||||
}
|
||||
|
||||
.client-device-traffic-lines .is-upload {
|
||||
stroke: color-mix(in oklch, var(--client-accent) 42%, var(--client-text));
|
||||
stroke-dasharray: 5 4;
|
||||
}
|
||||
|
||||
.client-device-traffic-lines path.is-new {
|
||||
stroke-dasharray: 1;
|
||||
stroke-dashoffset: 1;
|
||||
animation: client-device-traffic-line-draw 620ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
.client-device-traffic-lines path.is-new.is-upload {
|
||||
stroke-dasharray: 0.08 0.05;
|
||||
stroke-dashoffset: 0;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.client-device-traffic-lines .is-point {
|
||||
stroke-width: 3;
|
||||
stroke-linecap: round;
|
||||
@@ -775,6 +790,14 @@
|
||||
stroke: var(--client-accent);
|
||||
}
|
||||
|
||||
.client-device-traffic-cursor .is-point.is-download {
|
||||
stroke: var(--client-accent);
|
||||
}
|
||||
|
||||
.client-device-traffic-cursor .is-point.is-upload {
|
||||
stroke: color-mix(in oklch, var(--client-accent) 42%, var(--client-text));
|
||||
}
|
||||
|
||||
.client-device-traffic-time {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
@@ -817,6 +840,10 @@
|
||||
color: var(--client-accent);
|
||||
}
|
||||
|
||||
.client-device-traffic-point-tooltip .is-upload {
|
||||
color: color-mix(in oklch, var(--client-accent) 56%, oklch(0.92 0.008 145));
|
||||
}
|
||||
|
||||
@keyframes client-device-traffic-shift {
|
||||
from { opacity: 0.72; transform: translateX(calc(100% / var(--sample-count))); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
@@ -951,14 +978,14 @@
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 2;
|
||||
justify-self: center;
|
||||
width: min(480px, calc(100% - 24px));
|
||||
width: min(860px, calc(100% - 48px));
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
gap: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.client-gateway-summary-kicker,
|
||||
.client-gateway-traffic-heading > span {
|
||||
.client-gateway-traffic-total > small {
|
||||
color: var(--client-muted);
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
@@ -967,29 +994,59 @@
|
||||
}
|
||||
|
||||
.client-gateway-traffic-heading {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
align-items: end;
|
||||
gap: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-heading strong {
|
||||
.client-gateway-traffic-total {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-total > small {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-total > strong {
|
||||
color: var(--client-text);
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-speed {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
justify-self: end;
|
||||
gap: 18px;
|
||||
font-size: 11px;
|
||||
font-variant-numeric: tabular-nums;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-speed .is-download {
|
||||
color: var(--client-accent);
|
||||
}
|
||||
|
||||
.client-gateway-traffic-speed .is-upload {
|
||||
color: color-mix(in oklch, var(--client-accent) 48%, var(--client-text));
|
||||
}
|
||||
|
||||
.client-gateway-traffic-chart {
|
||||
width: 100%;
|
||||
min-height: 88px;
|
||||
min-height: 180px;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-chart .client-device-traffic-chart {
|
||||
grid-column: auto;
|
||||
grid-row: auto;
|
||||
width: 100%;
|
||||
height: 88px;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-freshness {
|
||||
@@ -1002,3 +1059,26 @@
|
||||
.client-gateway-traffic-freshness.is-stale {
|
||||
color: oklch(0.68 0.14 72);
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.client-gateway-summary {
|
||||
width: min(100%, calc(100vw - 52px));
|
||||
}
|
||||
|
||||
.client-gateway-traffic-heading {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-speed {
|
||||
justify-self: start;
|
||||
gap: 14px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.client-gateway-traffic-chart,
|
||||
.client-gateway-traffic-chart .client-device-traffic-chart {
|
||||
min-height: 130px;
|
||||
height: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.client-icon-tooltip {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
.client-subscription-refresh,
|
||||
.client-subscription-delete {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 0;
|
||||
@@ -247,9 +247,37 @@
|
||||
}
|
||||
|
||||
.client-subscription-heading {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 64px minmax(0, 1fr) 64px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.client-subscription-status {
|
||||
grid-column: 2;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
color: var(--client-accent);
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.client-subscription-status i {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
box-shadow: 0 0 8px currentColor;
|
||||
}
|
||||
|
||||
.client-subscription-actions {
|
||||
grid-column: 3;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.client-subscription-domain-button {
|
||||
@@ -264,6 +292,11 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.client-subscription-domain-button .client-subscription-label {
|
||||
display: block;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.client-subscription-summary {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
@@ -272,11 +305,11 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
gap: 5px;
|
||||
padding: 0 2px;
|
||||
color: var(--client-muted);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
cursor: default;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
@@ -288,19 +321,21 @@
|
||||
}
|
||||
|
||||
.client-subscription-label {
|
||||
font-size: 12px;
|
||||
color: var(--client-muted);
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.client-subscription-domain-button strong {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
color: var(--client-text);
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.055em;
|
||||
opacity: 0.88;
|
||||
font-size: 30px;
|
||||
font-weight: 650;
|
||||
letter-spacing: -0.05em;
|
||||
opacity: 0.96;
|
||||
text-shadow: 0 0 20px color-mix(in oklch, var(--client-accent) 24%, transparent);
|
||||
transition: opacity 300ms cubic-bezier(0.16, 1, 0.3, 1), text-shadow 300ms cubic-bezier(0.16, 1, 0.3, 1), transform 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
text-overflow: ellipsis;
|
||||
@@ -314,24 +349,32 @@
|
||||
}
|
||||
|
||||
.client-usage {
|
||||
width: min(100%, 250px);
|
||||
width: min(100%, 280px);
|
||||
min-height: 76px;
|
||||
display: grid;
|
||||
gap: 7px;
|
||||
margin: -10px auto 0;
|
||||
align-content: start;
|
||||
gap: 9px;
|
||||
margin: -6px auto 0;
|
||||
color: var(--client-muted);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.client-usage > span {
|
||||
.client-usage-summary {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.client-usage-summary > span,
|
||||
.client-usage-details > span {
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.client-usage > strong {
|
||||
.client-usage-summary > strong {
|
||||
color: var(--client-text);
|
||||
font-size: 14px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
transition: color 700ms ease, filter 700ms ease, text-shadow 700ms ease;
|
||||
}
|
||||
@@ -340,7 +383,7 @@
|
||||
animation: client-usage-glow 1100ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-usage.is-updated > strong {
|
||||
.client-usage.is-updated .client-usage-summary > strong {
|
||||
color: var(--client-accent);
|
||||
filter: brightness(1.25);
|
||||
text-shadow: 0 0 8px var(--client-accent), 0 0 22px color-mix(in oklch, var(--client-accent) 70%, transparent);
|
||||
@@ -358,7 +401,7 @@
|
||||
30% { box-shadow: 0 0 6px var(--client-accent), 0 0 20px var(--client-accent); filter: brightness(1.45); }
|
||||
}
|
||||
|
||||
.client-usage > strong small {
|
||||
.client-usage-summary > strong small {
|
||||
color: var(--client-muted);
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
@@ -379,13 +422,33 @@
|
||||
}
|
||||
|
||||
.client-usage-details {
|
||||
display: flex;
|
||||
min-height: 24px;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
align-items: baseline;
|
||||
column-gap: 6px;
|
||||
font-size: 9px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.client-usage-details > span {
|
||||
grid-column: 1 / -1;
|
||||
font-size: 8px;
|
||||
opacity: 0.72;
|
||||
}
|
||||
|
||||
.client-usage-details > strong {
|
||||
color: var(--client-text);
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.client-usage-details > small {
|
||||
color: var(--client-muted);
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.client-inline-error.is-subscription {
|
||||
top: calc(100% + 2px);
|
||||
}
|
||||
@@ -419,3 +482,9 @@
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.client-usage-summary > strong {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +189,36 @@
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.harbor-brand-content > svg,
|
||||
.harbor-brand-name > strong,
|
||||
.harbor-brand-name > em,
|
||||
.harbor-mode-stack {
|
||||
transition: filter 760ms ease, text-shadow 760ms ease, transform 760ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.harbor-brand-name > strong,
|
||||
.harbor-brand-name > em {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.harbor-brand.is-connected .harbor-brand-content > svg {
|
||||
filter: drop-shadow(0 0 5px color-mix(in oklch, var(--client-accent) 44%, transparent));
|
||||
}
|
||||
|
||||
.harbor-brand.is-connected .harbor-brand-content > svg,
|
||||
.harbor-brand.is-connected .harbor-brand-name > strong,
|
||||
.harbor-brand.is-connected .harbor-brand-name > em,
|
||||
.harbor-brand.is-connected .harbor-mode-stack {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.harbor-brand.is-connected .harbor-brand-name > strong,
|
||||
.harbor-brand.is-connected .harbor-brand-name > em,
|
||||
.harbor-brand.is-connected .harbor-mode-stack {
|
||||
text-shadow: 0 0 12px color-mix(in oklch, var(--client-accent) 34%, transparent);
|
||||
}
|
||||
|
||||
.client-shell.is-intro .harbor-brand-content {
|
||||
animation: harbor-startup-brand 760ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
@@ -367,6 +397,10 @@
|
||||
animation: harbor-mode-arrows-discovered 260ms 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||
}
|
||||
|
||||
.harbor-brand.is-connected .harbor-mode-swap {
|
||||
transform: translateY(calc(-50% - 4px));
|
||||
}
|
||||
|
||||
@keyframes harbor-mode-arrows-discovered {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -519,8 +553,9 @@
|
||||
}
|
||||
|
||||
.client-panel.is-gateway-home {
|
||||
grid-template-rows: minmax(0, 1fr) auto;
|
||||
row-gap: 28px;
|
||||
min-height: max(620px, calc(100dvh - 80px));
|
||||
grid-template-rows: minmax(260px, 1fr) auto;
|
||||
row-gap: 36px;
|
||||
}
|
||||
|
||||
.client-gateway-route-summary {
|
||||
@@ -558,7 +593,7 @@
|
||||
}
|
||||
|
||||
.client-panel.is-gateway-home .client-state-copy {
|
||||
min-height: 136px;
|
||||
min-height: 84px;
|
||||
}
|
||||
|
||||
@media (min-width: 921px) {
|
||||
@@ -590,6 +625,12 @@
|
||||
padding: 110px 6px 72px;
|
||||
}
|
||||
|
||||
.client-panel.is-gateway-home {
|
||||
min-height: calc(100dvh - 40px);
|
||||
grid-template-rows: minmax(320px, 1fr) auto;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.client-power-section,
|
||||
.client-form,
|
||||
.client-panel.is-setup .client-form {
|
||||
|
||||
@@ -118,6 +118,11 @@
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
|
||||
.client-device-traffic-lines path.is-new {
|
||||
stroke-dashoffset: 0;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.client-local-rules,
|
||||
.client-local-rules-toggle,
|
||||
.client-local-rules-toggle svg,
|
||||
@@ -151,6 +156,13 @@
|
||||
animation: none;
|
||||
}
|
||||
|
||||
.harbor-brand-content > svg,
|
||||
.harbor-brand-name > strong,
|
||||
.harbor-brand-name > em,
|
||||
.harbor-mode-stack {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.client-shell.is-intro .client-panel,
|
||||
.client-shell.is-intro .client-secondary-menu,
|
||||
.client-shell.is-intro .harbor-versions {
|
||||
|
||||
Reference in New Issue
Block a user