Refine VPN client instructions and subscription refresh flow
This commit is contained in:
@@ -79,6 +79,7 @@ p {
|
||||
}
|
||||
|
||||
.client-shell {
|
||||
position: relative;
|
||||
width: min(100%, 1100px);
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
@@ -86,6 +87,352 @@ p {
|
||||
color: var(--client-text);
|
||||
}
|
||||
|
||||
.client-instructions-toggle {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 14px;
|
||||
z-index: 30;
|
||||
width: 42px;
|
||||
height: 54px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--client-muted);
|
||||
cursor: pointer;
|
||||
transform: translateY(-50%);
|
||||
transition: transform 440ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-instructions-toggle svg {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 23px;
|
||||
height: 18px;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 1.7;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
overflow: visible;
|
||||
transition: transform 500ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-instructions-toggle path {
|
||||
opacity: 0;
|
||||
transform: translateX(-5px);
|
||||
transition: opacity 260ms ease, transform 480ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-instructions-toggle path:last-child {
|
||||
opacity: 1;
|
||||
transform: translateX(-4px);
|
||||
}
|
||||
|
||||
.client-instructions-toggle span {
|
||||
position: absolute;
|
||||
left: 48px;
|
||||
width: max-content;
|
||||
color: var(--client-text);
|
||||
font: 700 10px/1.2 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
|
||||
letter-spacing: 0.04em;
|
||||
opacity: 0;
|
||||
filter: blur(5px);
|
||||
pointer-events: none;
|
||||
transform: translateX(-8px);
|
||||
transition: opacity 350ms ease, filter 350ms ease, transform 500ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-instructions-toggle:hover,
|
||||
.client-instructions-toggle:focus-visible {
|
||||
outline: none;
|
||||
transform: translateY(-50%) translateX(3px);
|
||||
}
|
||||
|
||||
.client-instructions-toggle:hover path,
|
||||
.client-instructions-toggle:focus-visible path {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.client-instructions-toggle:hover span,
|
||||
.client-instructions-toggle:focus-visible span {
|
||||
opacity: 1;
|
||||
filter: blur(0);
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.client-instructions-toggle.is-open svg {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.client-instructions-toggle.is-open path {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.client-instructions-toggle.is-open path:first-child {
|
||||
opacity: 1;
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.client-instructions-toggle.is-open span {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.client-instructions {
|
||||
position: fixed;
|
||||
inset: 0 auto 0 0;
|
||||
z-index: 20;
|
||||
width: min(470px, 100vw);
|
||||
overflow-y: auto;
|
||||
background: color-mix(in oklch, var(--client-bg) 99%, var(--client-panel));
|
||||
color: var(--client-text);
|
||||
box-shadow: 26px 0 72px oklch(0.09 0.015 145 / 0.12);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateX(-104%);
|
||||
transition: transform 760ms cubic-bezier(0.16, 1, 0.3, 1), opacity 500ms ease, visibility 0s 760ms;
|
||||
}
|
||||
|
||||
.client-instructions.is-open {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(0);
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
.client-instructions-sheet {
|
||||
min-height: 100%;
|
||||
padding: 54px 34px 72px 72px;
|
||||
font-family: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
|
||||
}
|
||||
|
||||
.client-instructions-header {
|
||||
display: grid;
|
||||
gap: 9px;
|
||||
margin: 0 8px 38px;
|
||||
}
|
||||
|
||||
.client-instructions-header span,
|
||||
.client-instruction-summary > span {
|
||||
color: var(--client-muted);
|
||||
font-size: 9px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.client-instructions-header h2 {
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
letter-spacing: -0.045em;
|
||||
}
|
||||
|
||||
.client-instructions-intro {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
margin-top: 15px;
|
||||
color: var(--client-muted);
|
||||
font-size: 11px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.client-instructions-intro p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.client-instruction-list {
|
||||
display: grid;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.client-instruction-block {
|
||||
border: 0;
|
||||
border-radius: 22px;
|
||||
background: color-mix(in oklch, var(--client-panel) 56%, var(--client-bg));
|
||||
box-shadow: 0 14px 36px oklch(0.1 0.015 145 / 0.065);
|
||||
transition: background 300ms ease, box-shadow 500ms ease, transform 500ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-instruction-block:nth-child(even) {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.client-instruction-block:nth-child(3n) {
|
||||
margin-right: 9px;
|
||||
}
|
||||
|
||||
.client-instruction-block:hover,
|
||||
.client-instruction-block.is-open {
|
||||
background: color-mix(in oklch, var(--client-panel) 68%, var(--client-bg));
|
||||
box-shadow: 0 20px 48px oklch(0.1 0.015 145 / 0.095);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.client-instruction-block.is-open {
|
||||
animation: client-instruction-promote 520ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||
}
|
||||
|
||||
@keyframes client-instruction-promote {
|
||||
from { opacity: 0.72; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(-2px); }
|
||||
}
|
||||
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation: none;
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
|
||||
::view-transition-group(instruction-proxybridge),
|
||||
::view-transition-group(instruction-switchyomega),
|
||||
::view-transition-group(instruction-vscode),
|
||||
::view-transition-group(instruction-router) {
|
||||
animation-duration: 560ms;
|
||||
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.client-instruction-summary {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
gap: 7px;
|
||||
padding: 21px 46px 21px 22px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.client-instruction-summary:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.client-instruction-block:has(.client-instruction-summary:focus-visible) {
|
||||
background: color-mix(in oklch, var(--client-panel) 72%, var(--client-bg));
|
||||
box-shadow: 0 20px 48px oklch(0.1 0.015 145 / 0.11);
|
||||
}
|
||||
|
||||
.client-instruction-summary > i {
|
||||
position: absolute;
|
||||
top: 27px;
|
||||
right: 20px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.client-instruction-summary > i::before,
|
||||
.client-instruction-summary > i::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 0;
|
||||
width: 12px;
|
||||
height: 1px;
|
||||
background: var(--client-muted);
|
||||
transform-origin: center;
|
||||
transition: transform 520ms cubic-bezier(0.16, 1, 0.3, 1), opacity 360ms ease;
|
||||
}
|
||||
|
||||
.client-instruction-summary > i::after {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.client-instruction-block.is-open .client-instruction-summary > i::after {
|
||||
opacity: 0;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.client-instruction-block.is-open .client-instruction-summary > i::before {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.client-instruction-summary strong {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.client-instruction-summary small {
|
||||
max-width: 54ch;
|
||||
color: var(--client-muted);
|
||||
font-size: 10px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.client-instruction-reveal {
|
||||
display: grid;
|
||||
grid-template-rows: 0fr;
|
||||
opacity: 0;
|
||||
filter: blur(4px);
|
||||
transition: grid-template-rows 600ms cubic-bezier(0.16, 1, 0.3, 1), opacity 420ms ease, filter 500ms ease;
|
||||
}
|
||||
|
||||
.client-instruction-block.is-open .client-instruction-reveal {
|
||||
grid-template-rows: 1fr;
|
||||
opacity: 1;
|
||||
filter: blur(0);
|
||||
}
|
||||
|
||||
.client-instruction-body {
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
padding: 0 22px 24px;
|
||||
color: var(--client-muted);
|
||||
font-size: 11px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.client-instruction-body p,
|
||||
.client-instruction-body ol {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.client-instruction-body ol {
|
||||
display: grid;
|
||||
gap: 9px;
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
.client-instruction-body li::marker {
|
||||
color: var(--client-accent);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.client-instruction-body code {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 12px 14px;
|
||||
border-radius: 12px;
|
||||
background: color-mix(in oklch, var(--client-control) 84%, transparent);
|
||||
color: var(--client-text);
|
||||
font: 500 11px/1.5 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.client-instruction-body .client-instruction-note {
|
||||
padding: 11px 13px;
|
||||
border-radius: 12px;
|
||||
background: color-mix(in oklch, var(--client-control) 48%, transparent);
|
||||
color: var(--client-text);
|
||||
}
|
||||
|
||||
.client-instruction-body a {
|
||||
width: fit-content;
|
||||
color: var(--client-accent);
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.client-instruction-body a:hover {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
|
||||
.client-panel {
|
||||
position: relative;
|
||||
display: grid;
|
||||
@@ -899,6 +1246,22 @@ p {
|
||||
padding: 20px 6px;
|
||||
}
|
||||
|
||||
.client-instructions-toggle {
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.client-instructions-sheet {
|
||||
padding: 40px 18px 60px 58px;
|
||||
}
|
||||
|
||||
.client-instructions-header h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.client-instruction-block:nth-child(n) {
|
||||
margin-inline: 0;
|
||||
}
|
||||
|
||||
.client-form {
|
||||
position: static;
|
||||
width: 100%;
|
||||
@@ -927,6 +1290,15 @@ p {
|
||||
.client-access-tab,
|
||||
.client-access-point,
|
||||
.client-copy-feedback,
|
||||
.client-instructions,
|
||||
.client-instructions-toggle,
|
||||
.client-instructions-toggle svg,
|
||||
.client-instructions-toggle path,
|
||||
.client-instructions-toggle span,
|
||||
.client-instruction-block,
|
||||
.client-instruction-reveal,
|
||||
.client-instruction-summary > i::before,
|
||||
.client-instruction-summary > i::after,
|
||||
.client-subscription-edit,
|
||||
.client-subscription-edit::after,
|
||||
.client-subscription-summary,
|
||||
|
||||
Reference in New Issue
Block a user