Topology: a readable card per device
Lint / JS (eslint) (push) Successful in 7s
Lint / Python (flake8) (push) Successful in 1m16s
Lint / Notify on failure (push) Skipped
Lint / Deploy (push) Skipped
Security / Python Security (bandit) (push) Successful in 1m42s
Lint / Python (flake8) (pull_request) Successful in 1m41s
Test / Python Tests (pytest) (push) Successful in 2m28s
Lint / JS (eslint) (pull_request) Successful in 10s
Lint / Notify on failure (pull_request) Skipped
Lint / Deploy (pull_request) Skipped
Security / Python Security (bandit) (pull_request) Successful in 1m22s
Test / Python Tests (pytest) (pull_request) Successful in 1m37s

Drawn to true scale, the 4U servers dwarfed the switches and no label
could be read without zooming. Every device is now a card of the same
height: its name and state on top, and below that its real faceplate
(cropped to the ports) or, for a server, its front and a socket per NIC.
Cables meet the card edge right at the port, with a short tail to it.

The internet, modem and gateway sit side by side along the top, and
unknown devices share the row of the gear on their switch, so the whole
network fits a normal screen. On a phone the canvas takes the diagram's
shape instead of leaving most of it empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-14 19:58:29 -05:00
co-authored by Claude Opus 5.5
parent abe88df3a4
commit 7dba1750ee
5 changed files with 197 additions and 106 deletions
+19 -2
View File
@@ -1417,7 +1417,7 @@ body.fp-marks-off .fp-svg .fp-mark { display: none; }
/* ── Topology page ─────────────────────────────────────────────────── */
.tp-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin: 8px 0 10px; }
.tp-filters { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.tp-filter { display: inline-flex; align-items: center; gap: 6px; font-size: .78em; color: var(--text-dim); cursor: pointer; }
.tp-filter { display: inline-flex; align-items: center; gap: 6px; font-size: .78em; color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.tp-zoom { display: inline-flex; gap: 4px; }
.tp-updated { margin-left: auto; font-size: .72em; color: var(--text-muted); }
.tp-warnings { border: 1px solid var(--amber); color: var(--amber); background: var(--amber-dim); padding: 8px 12px; margin-bottom: 10px; font-size: .8em; }
@@ -1504,7 +1504,7 @@ body.fp-marks-off .fp-svg .fp-mark { display: none; }
.tp-strip { fill: #1b1f24; stroke: #2f363f; stroke-width: 3; }
.tp-nic-rj45, .tp-nic-sfp { fill: #0b0d10; stroke: #59626e; stroke-width: 3; }
.tp-nic-sfp-in { fill: #23272d; }
.tp-nic-name { font-family: var(--font); font-size: 18px; fill: #aab4bf; }
.tp-nic-name { font-family: var(--font); font-size: 17px; fill: #aab4bf; }
.tp-nic-led { fill: #3a3f45; }
.tp-nic-up .tp-nic-led { fill: #2fd36b; }
.tp-nic-up .tp-nic-rj45, .tp-nic-up .tp-nic-sfp { stroke: #8f9aa6; }
@@ -1597,3 +1597,20 @@ body.fp-marks-off .fp-svg .fp-mark { display: none; }
.tp-key-down { stroke: #e0312b; stroke-dasharray: 6 4; }
.tp-key-ghost { stroke: #e0312b; stroke-dasharray: 1 5; }
.tp-key-warn { color: #ffb300; font-weight: 700; }
/* Topology cards */
.tp-card { fill: #121821; stroke: #2a3440; stroke-width: 3; }
[data-theme="light"] .tp-card { fill: #ffffff; stroke: #c9d1da; }
.tp-band { fill: #0a0e13; stroke: #1c242e; stroke-width: 2; }
[data-theme="light"] .tp-band { fill: #eef1f4; stroke: #dde3ea; }
.tp-card-name { font-family: var(--font); font-size: 44px; font-weight: 700; fill: var(--text); letter-spacing: .01em; }
.tp-card-sub { font-family: var(--font); font-size: 28px; fill: var(--text-muted); }
.tp-card-stripe { fill: #6b737d; }
.tp-stripe-up { fill: #2fd36b; }
.tp-stripe-degraded { fill: #ffb300; }
.tp-stripe-down { fill: #e0312b; }
.tp-node-link:hover .tp-card, .tp-node-link:focus-visible .tp-card { stroke: var(--amber); }
.tp-kind-stub .tp-card, .tp-kind-group .tp-card { stroke-dasharray: 14 10; }
.tp-kind-group .tp-node-link { cursor: pointer; }
.tp-pigtail { stroke-width: 5 !important; stroke-dasharray: none !important; }
[data-theme="light"] .tp-nic-name { fill: #4b5562; }