3 Commits

Author SHA1 Message Date
Daniel Redetzke 606b3fe89f Keep the sidebar in view on long pages
Beside the page, the sidebar now stays in place while the page scrolls,
so the account link and Sign out are always visible; it scrolls by
itself in very short windows. On a phone it still stacks above the page.
Also show the version with one 'v': release builds already start with it.
2026-10-04 16:36:30 +03:00
Daniel Redetzke c7340d011a README: screenshots of the web interface
Seven pages captured from a demo instance with sample data from the
simulator: dashboard (under the introduction), peers, peer, server,
settings, my account and sign-in. Images live in screenshots/.
2026-10-04 16:31:01 +03:00
Daniel Redetzke 9220ff54aa README: show the Hannya logo at the top 2026-10-04 16:14:54 +03:00
10 changed files with 23 additions and 1 deletions
+19
View File
@@ -1,3 +1,7 @@
<p align="center">
<img src="favicon.svg" width="120" height="120" alt="GHOSTWIRE logo: the Hannya mask">
</p>
# GHOSTWIRE
**ゴーストワイヤー** · A self-hosted WireGuard server manager in a single Go
@@ -8,6 +12,8 @@ remove), hands out client configs as a download or QR code, and records traffic
and connection history per peer. There are no install scripts and no
dependencies on the server: the binary installs, updates and removes itself.
![Dashboard with peers online, traffic of the last 24 hours, the peer list and recent activity](screenshots/dashboard.png)
## Features
- **One file of state:** everything lives in `config.json`. The kernel is
@@ -34,6 +40,19 @@ dependencies on the server: the binary installs, updates and removes itself.
- **HTTPS built in:** Let's Encrypt, a self-signed certificate, your own
certificate files, or plain HTTP behind a reverse proxy.
## Screenshots
| | |
|---|---|
| ![Peers list with status, endpoint, latency sparklines and 30-day traffic](screenshots/peers.png) | ![Peer page with traffic and latency charts, connection details and history](screenshots/peer.png) |
| **Peers:** status, endpoint, latency and traffic at a glance | **Peer:** traffic, latency, connection history and settings |
| ![Server page with health checks, interface, endpoint, client defaults and firewall](screenshots/server.png) | ![Settings with users, web interface and API tokens](screenshots/settings.png) |
| **Server:** health, address plan, client defaults and firewall | **Settings:** users, web interface and API tokens |
| ![My account page with profile, password and own app tokens](screenshots/account.png) | ![Sign-in page](screenshots/login.png) |
| **My account:** profile, password and your app tokens | **Sign-in** |
The screenshots show sample data from the built-in simulator.
## Security
- **Client private keys are never stored.** A config is shown once, as a
+3
View File
@@ -66,6 +66,9 @@ a.brand, a.brand:hover { color: #fff; text-decoration: none; }
.side .avatar { width: 28px; height: 28px; border-radius: 50%; background: #3a3b41; display: grid; place-items: center; flex: none; font-size: 13px; font-weight: 600; color: #fff; }
.side .footrow { display: flex; justify-content: space-between; padding: 10px 12px 0; }
.main { flex: 999 1 560px; min-width: 0; padding: 32px 32px 56px; }
/* Beside the page (not stacked above it on a phone), the sidebar stays in
place while the page scrolls, so the account link is always visible. */
@media (min-width: 800px) { .side { position: sticky; top: 0; height: 100vh; height: 100dvh; overflow-y: auto; } }
.wrap { max-width: 1120px; margin: 0 auto; display: flex; flex-direction: column; gap: 20px; }
@media (max-width: 640px) { .main { padding: 20px 16px 40px; } }
+1 -1
View File
@@ -518,7 +518,7 @@
h('span', null, h('strong', null, me.name), h('span', null, 'My account')))),
h('div', { class: 'footrow' },
h('button', { type: 'button', onClick: logout }, 'Sign out'),
h('span', null, 'v' + me.version))));
h('span', null, 'v' + me.version.replace(/^v/, '')))));
main = h('main', { class: 'main', id: 'main' });
app.replaceChildren(h('div', { class: 'shell' }, nav, main));
refreshSide();
Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB