Files
harbor-net/.codex/skills/design-vpn-client-ui/SKILL.md
T
dokril 4c58384056
Build and Deploy Gateway / build-and-push (push) Successful in 37s
Build and Deploy Gateway / deploy (push) Successful in 19s
Harden traffic history worker lifecycle and query performance
2026-09-19 09:58:54 +03:00

6.1 KiB

name, description
name description
design-vpn-client-ui Use when changing or reviewing Harbor Connect and Gateway client UI. Apply the established visual and motion language; not for administrative Gateway UI unless explicitly requested.

Design VPN Client UI

Preserve the repo's focused one-screen VPN client language: a centered primary action, quiet technical typography, mode-specific accents, and motion that makes live state and interaction legible without moving layout.

Workflow

  1. Inspect the affected client component, state owner, relevant styles, and nearest analogue. Read PRODUCT.md when product behavior or mode semantics change; expand context when shared invariants require it.
  2. Inspect supplied evidence and trace the real DOM and state change that causes the visual issue. Follow repository testing policy; do not launch manual or interactive visual testing unless the user explicitly requests it in the current prompt.
  3. Read visual-language.md for layout, hierarchy, color, and typography work.
  4. Read motion-and-interaction.md for animation, hover, refresh, input, copy, or state-transition work.
  5. Reuse existing React state, CSS variables, formatters, and API paths. Prefer a narrow CSS/markup change over a new abstraction or dependency.
  6. Keep geometry stable across every state. Reserve space before animating content.
  7. Implement prefers-reduced-motion alongside every new animation.
  8. Run focused automated checks for affected behavior and npm run build for client code changes; use the full npm test suite when shared behavior changes or narrower evidence is insufficient. Documentation-only work uses structural/link checks and git diff --check. Manual visual inspection requires an explicit request in the current prompt.

Communicating a proposed change

For a local correction, report the result and focused evidence briefly. For a change spanning several owners or state lifecycles, use one compact table of affected modules plus the relevant states, accessibility, and motion decisions. Omit empty sections and unrelated modules.

Non-negotiable decisions

  • Keep the power action on the screen's central vertical axis. Place subscription content to its right without shifting that axis.
  • Keep the power hit target generous while rendering only the icon, never a large enclosing accent circle.
  • Drive every active accent from the current mode token: Connect is blue-green; Gateway is orange. Keep inactive power gray, including hover, and preserve semantic warning/error colors.
  • Never let labels, timers, feedback, icons, progress, or server rows shift neighboring content.
  • Animate state, opacity, blur, glow, color, filter, and transform. Do not animate layout properties.
  • Make live behavior visibly alive: running processes, changing values, mode changes, and interactive affordances should communicate through restrained motion instead of abrupt static replacement.
  • Give every actionable icon a semantic hover/focus response; rotate cyclic actions, move the physical part of object-like controls, and keep their hit targets fixed.
  • Let every visible cycle finish and return to its resting coordinates before stopping. Never cancel a hover animation, spinner, or list exit at an arbitrary frame.
  • Animate dynamic rows through complete enter and exit phases; keep a departing row mounted until its exit finishes, with immediate removal under reduced motion.
  • Animate only what changed. Keep unchanged digits, labels, icons, and surrounding geometry stable.
  • Keep tooltips outside transformed, rotating, glowing, or filtered controls. Show them quickly above the control as independent translucent cloud surfaces.
  • Prefer one clear value over unsupported detail. Hide subscription fields the provider does not supply.
  • Keep client UI compact and calm. Do not introduce dashboard cards, decorative chrome, or admin-console density.
  • Do not use a modal, popup, or blocking backdrop unless the user explicitly asks for one. Prefer inline disclosure or a non-modal layer that preserves the main screen.
  • When the owner explicitly chooses modal treatment for critical confirmations, reuse one accessible full-screen confirmation popup: blur and block the background, reveal from center, then stage text and actions.
  • Avoid borders, divider lines, and framed regions by default. Build hierarchy with spacing, typography, subtle surface changes, light, and depth; use a line only when it communicates an essential state.
  • In client-side editors, prefer flat text controls and accessible custom pickers over browser-native menus when the native surface breaks the visual language. Do not append another blank row until the current row is complete.

Acceptance pass

Check the affected behaviors below using automated evidence where possible. Shared layout or motion changes require broader coverage; a local correction does not require exercising unrelated controls. Manual inspection remains limited to an explicit request in the current prompt:

  • Power on/off is unmistakable without reading the label.
  • Switching on/off preserves the exact positions of title, timer, and hint.
  • Switching Connect/Gateway crossfades status in a fixed slot, changes the full accent palette, and clearly de-emphasizes data irrelevant to the active route.
  • A timer tick animates only changed digits and reads as a soft flow, never a blink.
  • Hover motion completes its current cycle and settles before stopping; ambient affordance motion remains subtle and infrequent.
  • Tooltips remain upright, unfiltered, above adjacent content, and visually consistent across controls.
  • Refresh and copy feedback cannot change element width or alignment.
  • Server separators are compact and only slightly wider than their content.
  • Repeated polling does not replay decorative list animations.
  • Manual refresh has an obvious but non-jarring response.
  • Icon-only controls respond on hover and focus, active cyclic work spins, and durable states such as pinned remain legible at rest.
  • Keyboard focus remains visible even when the text caret is intentionally hidden.
  • Narrow screens return to a simple single-column layout.