diff --git a/src/web/components/ClientOverviewPage.jsx b/src/web/components/ClientOverviewPage.jsx index 1221b7a..cd03c83 100644 --- a/src/web/components/ClientOverviewPage.jsx +++ b/src/web/components/ClientOverviewPage.jsx @@ -105,12 +105,18 @@ function HarborBrand({ isGateway, gatewayAvailable, gatewayDirect, busy, onSetGa className="harbor-brand-control" type="button" aria-label={label} + aria-describedby="harbor-mode-tooltip" aria-pressed={gatewayDirect} - title={label} disabled={busy} onClick={() => onSetGatewayAuto(!gatewayDirect)} > {content} + + {gatewayDirect ? 'Harbor Gateway активен' : 'Harbor Gateway доступен'} + {gatewayDirect + ? 'Трафик идёт через Gateway в этой сети. Нажмите, чтобы использовать локальный VPN.' + : 'Сейчас используется локальный VPN. Нажмите, чтобы направить трафик через Gateway.'} + :
{content}
} ); diff --git a/src/web/styles.css b/src/web/styles.css index 6ceb39b..d70bb22 100644 --- a/src/web/styles.css +++ b/src/web/styles.css @@ -110,6 +110,7 @@ p { } .harbor-brand-control { + position: relative; appearance: none; border: 0; border-radius: 7px; @@ -198,7 +199,7 @@ p { .harbor-mode-stack { position: relative; display: inline-block; - width: 7.2em; + width: 4.5em; height: 1.25em; } @@ -238,7 +239,7 @@ p { .harbor-brand .harbor-mode-swap { position: absolute; top: 50%; - left: calc(100% + 12px); + left: calc(100% + 4px); width: 14px; height: 14px; color: var(--harbor-connect); @@ -248,6 +249,44 @@ p { transition: color 320ms ease, opacity 320ms ease, transform 420ms cubic-bezier(0.16, 1, 0.3, 1); } +.harbor-mode-tooltip { + position: absolute; + top: calc(100% + 12px); + left: 50%; + width: 116px; + display: grid; + gap: 2px; + padding: 5px 6px; + border-radius: 5px; + background: color-mix(in oklch, var(--client-panel) 94%, var(--client-bg)); + box-shadow: 0 6px 20px oklch(0.08 0.015 145 / 0.16); + color: var(--client-muted); + font-size: 4px; + line-height: 1.5; + letter-spacing: 0; + text-align: left; + opacity: 0; + visibility: hidden; + filter: blur(2px); + pointer-events: none; + transform: translate(-50%, -3px); + transition: opacity 240ms ease, filter 320ms ease, transform 400ms cubic-bezier(0.16, 1, 0.3, 1), visibility 0s 400ms; +} + +.harbor-mode-tooltip strong { + color: var(--client-text); + font-size: 4.2px; +} + +.harbor-brand-control:hover .harbor-mode-tooltip, +.harbor-brand-control:focus-visible .harbor-mode-tooltip { + opacity: 1; + visibility: visible; + filter: blur(0); + transform: translate(-50%, 0); + transition-delay: 120ms, 120ms, 120ms, 0s; +} + .harbor-brand.is-gateway-active .harbor-mode-swap { color: var(--harbor-gateway); } @@ -1625,7 +1664,8 @@ p { } .harbor-mode-stack em, - .harbor-brand .harbor-mode-swap { + .harbor-brand .harbor-mode-swap, + .harbor-mode-tooltip { transition: none; }