Files
harbor-net/.codex/skills/design-vpn-client-ui/SKILL.md
Dmitriy Petrov fa3b455fab
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 14s
Build and Deploy Gateway / deploy (push) Successful in 1s
Refine VPN client instructions and subscription refresh flow
2026-07-11 12:34:14 +03:00

46 lines
3.5 KiB
Markdown

---
name: design-vpn-client-ui
description: Design, implement, review, or refine the client-facing VPN interfaces in this repository using the established calm monospace visual language and smooth state-driven motion. Use for the current macOS client and future end-user gateway client screens, especially power controls, subscriptions, traffic usage, proxy copy controls, server selection, responsive layout, hover feedback, transitions, and animation polish. Do not use for the administrative gateway UI unless the user explicitly asks to apply the client visual language there.
---
# Design VPN Client UI
Preserve the repo's focused one-screen VPN client language: a centered primary action, quiet technical typography, restrained green state color, and motion that feels slow, fluid, and deliberate without moving layout.
## Workflow
1. Read `PRODUCT.md` and the complete client component and styles before editing.
2. Inspect the supplied screenshot or live UI. Trace the real DOM and state change that causes the visual issue.
3. Read [visual-language.md](references/visual-language.md) for layout, hierarchy, color, and typography work.
4. Read [motion-and-interaction.md](references/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 `npm test`, `npm run build`, and `git diff --check`. Visually inspect when a runnable client is available.
## 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 green circle.
- Use green only for active, selected, successful, or refreshed states. Keep inactive power gray, including hover.
- 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.
- Let visible cycles finish. Never stop a spinner mid-turn or remount a list before its exit animation completes.
- 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.
- 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.
## Acceptance pass
Before handing off, verify:
- Power on/off is unmistakable without reading the label.
- Switching on/off preserves the exact positions of title, timer, and hint.
- 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.
- Keyboard focus remains visible even when the text caret is intentionally hidden.
- Narrow screens return to a simple single-column layout.