diff --git a/web/zebra-spaces.html b/web/zebra-spaces.html
index 170dfc7..401c837 100644
--- a/web/zebra-spaces.html
+++ b/web/zebra-spaces.html
@@ -16,17 +16,73 @@
font-family: monospace; background: #fff; color: #000;
padding: 1rem 1.5rem; max-width: none; margin: 0 auto;
}
- /* Dark mode = literal invert. CSS filter flips every painted colour on
- * the page in one shot, then hue-rotate corrects what would otherwise
- * read as cyan instead of orange / magenta instead of green. Re-invert
- * the things we want to look RIGHT instead of merely opposite: video
- * tiles, the QR canvas, and any inline raster. */
- html.theme-dark body { filter: invert(1) hue-rotate(180deg); background: #fff; }
- html.theme-dark video,
- html.theme-dark canvas,
- html.theme-dark img { filter: invert(1) hue-rotate(180deg); }
- /* the theme toggle button itself sits inside the inverted area, so
- * its own colours flip automatically — no extra rule needed */
+ /* Dark mode = pure black canvas, dim text, low total light emission.
+ * Explicit overrides instead of filter:invert so the page looks
+ * intentional in both modes rather than mathematically flipped. */
+ html.theme-dark { background: #000; }
+ html.theme-dark body { background: #000; color: #ccc; }
+ html.theme-dark a { color: #9cf; }
+ html.theme-dark .sub, html.theme-dark .sub a, html.theme-dark .note,
+ html.theme-dark .status-line { color: #888; }
+ html.theme-dark .timeline { border-right-color: #222; }
+ html.theme-dark .timeline-frame { background: #000; border-color: #222; }
+ /* buttons + inputs */
+ html.theme-dark button,
+ html.theme-dark .game-tabs button,
+ html.theme-dark .theme-toggle {
+ background: #000; color: #ccc; border-color: #444;
+ }
+ html.theme-dark button:hover:not(:disabled),
+ html.theme-dark .game-tabs button:hover:not(.active),
+ html.theme-dark .theme-toggle:hover { background: #1a1a1a; }
+ html.theme-dark button.invert { background: #ccc; color: #000; border-color: #ccc; }
+ html.theme-dark button.invert:hover:not(:disabled) { background: #999; }
+ html.theme-dark .game-tabs button.active { background: #ccc; color: #000; border-color: #ccc; }
+ html.theme-dark input[type=text],
+ html.theme-dark input[type=password],
+ html.theme-dark textarea,
+ html.theme-dark select {
+ background: #0a0a0a; color: #ccc; border-color: #333;
+ }
+ html.theme-dark .dot { background: #000; border-color: #444; }
+ html.theme-dark .dot.ok { background: #0a0; border-color: #0a0; }
+ html.theme-dark .meter { background: #000; border-color: #444; }
+ html.theme-dark .meter-fill { background: #ccc; }
+ /* badges */
+ html.theme-dark .badge.host { background: #ccc; color: #000; border-color: #ccc; }
+ html.theme-dark .badge.cohost { background: #666; color: #000; border-color: #666; }
+ html.theme-dark .badge.speaker { background: #000; color: #ccc; border-color: #ccc; }
+ html.theme-dark .badge.listener{ background: #000; color: #888; border-color: #444; }
+ html.theme-dark .pub-short { color: #777; }
+ html.theme-dark .handle .me { color: #6c6; }
+ html.theme-dark .raised { color: #f66; }
+ /* log */
+ html.theme-dark .log { background: #050505; border-color: #333; }
+ html.theme-dark .log-line .ts { color: #666; }
+ html.theme-dark .log-line.err { color: #f66; }
+ html.theme-dark .status-line.ok { color: #6c6; }
+ html.theme-dark .status-line.err { color: #f66; }
+ /* notice banners */
+ html.theme-dark .notice-banner { background: #1a1a00; border-color: #553; color: #ccc; }
+ html.theme-dark .notice-banner.warn { background: #1a0000; border-color: #500; color: #f66; }
+ html.theme-dark .notice-banner.info { background: #001a00; border-color: #050; color: #6c6; }
+ /* latency rows */
+ html.theme-dark .lat-row { border-bottom-color: #1a1a1a; }
+ html.theme-dark .lat-row .lat-name { color: #aaa; }
+ html.theme-dark .lat-row .lat-loss::before,
+ html.theme-dark .lat-row .lat-jit::before { color: #666; }
+ html.theme-dark .lat-row .lat-path { color: #666; }
+ html.theme-dark .lat-row.lat-good .lat-rtt, html.theme-dark .lat-row.lat-good .lat-loss, html.theme-dark .lat-row.lat-good .lat-jit { color: #6c6; }
+ html.theme-dark .lat-row.lat-mid .lat-rtt, html.theme-dark .lat-row.lat-mid .lat-loss, html.theme-dark .lat-row.lat-mid .lat-jit { color: #ec0; }
+ html.theme-dark .lat-row.lat-bad .lat-rtt, html.theme-dark .lat-row.lat-bad .lat-loss, html.theme-dark .lat-row.lat-bad .lat-jit { color: #f66; }
+ html.theme-dark .lat-row.lat-na .lat-rtt, html.theme-dark .lat-row.lat-na .lat-loss, html.theme-dark .lat-row.lat-na .lat-jit { color: #555; }
+ /* vault */
+ html.theme-dark .vault-panel { border-color: #444; }
+ /* page-integrity footer */
+ html.theme-dark footer { color: #555 !important; }
+ html.theme-dark footer span { color: #555 !important; }
+ html.theme-dark footer a { color: #777 !important; }
+
.theme-toggle {
position: fixed; top: 0.6rem; right: 0.8rem; z-index: 9999;
background: #fff; color: #000; border: 1px solid #000;
@@ -2118,8 +2174,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');