From ca6ba83950216c24b70aae05e6a6e8702321feb2 Mon Sep 17 00:00:00 2001 From: m17hr1l Date: Sun, 7 Jun 2026 01:13:51 +0200 Subject: [PATCH] stage-exp-c explore: HTML template + landing layout --- src/psyc/cockpit/static/cockpit.css | 232 ++++++++++++++++++ .../cockpit/templates/federation_explore.html | 145 +++++++++++ 2 files changed, 377 insertions(+) create mode 100644 src/psyc/cockpit/templates/federation_explore.html diff --git a/src/psyc/cockpit/static/cockpit.css b/src/psyc/cockpit/static/cockpit.css index a6d5934..10be382 100644 --- a/src/psyc/cockpit/static/cockpit.css +++ b/src/psyc/cockpit/static/cockpit.css @@ -1554,3 +1554,235 @@ body.wide #federation-network-graph { height: 720px; } color: var(--muted); font-size: 12px; font-style: italic; text-align: center; padding: 22px 0; } + +/* =================================================================== + * federation explorer — public transparency page + * Public-facing variant of the admin federation network UI. Reuses the + * fn-* graph classes; fe-* is just the chrome around it. + * =================================================================== */ + +.fe-page { background: var(--bg); } +.fe-topbar { gap: 18px; } +.fe-topbar .nav-toggle, .fe-topbar .nav { display: none; } +.fe-badge { + display: inline-flex; align-items: center; gap: 8px; + padding: 4px 12px; + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 10.5px; + color: var(--accent); + background: rgba(30,200,255,0.08); + border: 1px solid var(--accent); + border-radius: 999px; + letter-spacing: 0.10em; + text-transform: uppercase; + box-shadow: 0 0 12px var(--accent-glow); + margin-left: auto; +} +.fe-badge-dot { + width: 7px; height: 7px; border-radius: 50%; + background: var(--accent); + box-shadow: 0 0 8px var(--accent); + animation: fe-pulse 1.8s ease-in-out infinite; +} +@keyframes fe-pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.4; transform: scale(1.4); } +} + +.fe-hero { padding: 28px 32px; } +.fe-hero-head { margin-bottom: 14px; } +.fe-title { + margin: 0; + font-family: var(--font-display); + font-size: 32px; + font-weight: 700; + letter-spacing: 0.02em; + color: var(--text); +} +.fe-title::before { + content: "⌖ "; + color: var(--accent); + text-shadow: 0 0 12px var(--accent-glow); +} +.fe-sub { + margin: 6px 0 0; + color: var(--accent); + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 13px; + word-break: break-all; + text-shadow: 0 0 8px var(--accent-glow); +} +.fe-intro { + margin: 14px 0 0; + max-width: 920px; + color: var(--text); + line-height: 1.55; + font-size: 14px; +} +.fe-intro strong { color: var(--accent); font-weight: 600; } +.fe-intro-sub { color: var(--muted); font-size: 12px; margin-top: 10px; } +.fe-fp { + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 11px; + background: var(--panel); + border: 1px solid var(--border); + border-radius: 3px; + padding: 2px 6px; + color: var(--accent); + word-break: break-all; +} + +.fe-kpi-panel { padding: 18px 22px; } +.fe-kpis { gap: 14px; } +.fe-kpis .fn-stat { min-width: 130px; } +.fe-kpi-verify .fn-stat-value { font-size: 18px; } +.fe-kpi-verify .fn-stat-value.fe-verify-ok { color: var(--green); text-shadow: 0 0 10px rgba(74,222,128,0.45); } +.fe-kpi-verify .fn-stat-value.fe-verify-bad { color: var(--red); text-shadow: 0 0 10px rgba(248,113,113,0.45); } + +.fe-verify-row { + display: flex; align-items: center; gap: 12px; flex-wrap: wrap; + margin-top: 14px; + padding-top: 14px; + border-top: 1px dashed var(--border); +} +.fe-verify-btn { + font-family: var(--font-display); + letter-spacing: 0.08em; + text-transform: uppercase; + font-size: 11px; + font-weight: 600; +} +.fe-verify-result { + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 12px; + color: var(--muted); +} +.fe-verify-result.fe-verify-ok { color: var(--green); } +.fe-verify-result.fe-verify-bad { color: var(--red); } +.fe-verify-link { + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 11px; + color: var(--muted); + text-decoration: none; + border-bottom: 1px dotted var(--border); +} +.fe-verify-link:hover { color: var(--accent); border-color: var(--accent); } + +.fe-stage { margin-top: 8px; } + +.fe-walk { + margin-top: 16px; + padding: 14px 18px; + background: var(--panel-2); + border: 1px solid var(--border); + border-radius: 6px; + min-height: 56px; +} +.fe-walk-empty { + margin: 0; color: var(--muted); + font-style: italic; font-size: 13px; +} +.fe-walk-card { + display: grid; + grid-template-columns: 1fr auto; + gap: 16px; + align-items: center; +} +.fe-walk-card-body { min-width: 0; } +.fe-walk-card-title { + margin: 0 0 4px; + font-family: var(--font-display); + font-size: 16px; + font-weight: 600; + color: var(--text); + word-break: break-all; +} +.fe-walk-card-fp { + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 11px; + color: var(--muted); + word-break: break-all; +} +.fe-walk-card-stats { + display: flex; flex-wrap: wrap; gap: 8px; + margin-top: 10px; + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 11px; +} +.fe-walk-card-stats .k { color: var(--muted); } +.fe-walk-card-stats .v { color: var(--accent); } +.fe-walk-card-stats > span { + padding: 2px 8px; + border: 1px solid var(--border); + border-radius: 999px; + background: var(--panel); +} +.fe-walk-cta { + display: inline-flex; align-items: center; gap: 8px; + padding: 10px 18px; + font-family: var(--font-display); + font-size: 13px; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--bg); + background: var(--accent); + border: 1px solid var(--accent); + border-radius: 5px; + text-decoration: none; + box-shadow: 0 0 14px var(--accent-glow); + white-space: nowrap; +} +.fe-walk-cta:hover { + background: #66daff; + text-decoration: none; +} +.fe-walk-cta-disabled { + color: var(--muted); + background: transparent; + border-color: var(--border); + box-shadow: none; + cursor: not-allowed; +} + +.fe-vouches-panel .fe-vouches-in-list { + list-style: none; + margin: 0; padding: 0; +} +.fe-vouches-in-list li { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 12px; + align-items: center; + padding: 8px 10px; + border-bottom: 1px dashed var(--border); + font-family: ui-monospace, Menlo, Consolas, monospace; + font-size: 12px; +} +.fe-vouches-in-list li:last-child { border-bottom: 0; } +.fe-vouches-in-list .fp { color: var(--accent); word-break: break-all; } +.fe-vouches-in-list .ts { color: var(--muted); font-size: 11px; } +.fe-vouches-in-empty { + color: var(--muted); font-style: italic; + display: block !important; + text-align: center; + padding: 18px 0; +} + +.fe-footer { + margin-top: 36px; + text-align: center; + color: var(--muted); + font-size: 11px; + font-family: ui-monospace, Menlo, Consolas, monospace; + letter-spacing: 0.05em; +} + +@media (max-width: 720px) { + .fe-hero { padding: 18px 16px; } + .fe-title { font-size: 24px; } + .fe-walk-card { + grid-template-columns: 1fr; + } + .fe-walk-cta { width: 100%; justify-content: center; } +} diff --git a/src/psyc/cockpit/templates/federation_explore.html b/src/psyc/cockpit/templates/federation_explore.html new file mode 100644 index 0000000..f38fe22 --- /dev/null +++ b/src/psyc/cockpit/templates/federation_explore.html @@ -0,0 +1,145 @@ + + + + + + + + Federation Explorer — psyc + + + + + + + + + + + + +
+ + psyc + operations cockpit + + + PUBLIC · TRANSPARENT + +
+ NN-sc — Security/Control +
+
+ +
+
+
+

Federation Explorer

+

{{ domain or fingerprint }}

+
+

+ This is a public transparency view of the psyc federation this node sits inside. + Anyone on the internet can verify the trust network — who has vouched for whom, + which signals are corroborated, and that the transparency log hasn't been rewritten. + Click any peer in the graph to inspect it, then jump to that peer's own explorer. +

+

+ Self fingerprint: + {{ fingerprint }} + +

+
+ +
+
+
direct peers
+
vouches out
+
vouches in
+
signals (24h)
+
corroborations (24h)
+
translog entries
+
log integrity
+
+
+ + + raw log JSON + signed payload +
+
+ +
+
+

Trust network

+ direct · transitive +
+

+ Self at the center, directly-trusted peers around it, + peers-of-peers (learned from each trusted peer's signed feed) on the outer ring. + Edges: vouches (solid), signals (dashed, thickness ∝ 24h volume), + knows (dotted grey), corroborate (faint pulse — two peers reporting the same signal). +

+ +
+
+
+ + + +
+ + self + trusted + transitive + + drag · scroll to zoom · click a peer to walk to its explorer +
+ +
+
loading federation network…
+ +
+ +
+

Click any peer in the graph above to inspect it and walk to its federation view.

+
+
+ +
+
+

Who vouches for this node

+ inbound +
+

+ Each entry is a signed vouch naming this node as target, issued by a peer we currently trust. + Click a fingerprint to highlight that peer in the graph above. +

+
    +
  • no inbound vouches yet
  • +
+
+
+ + + + + + +