diff --git a/decnet_web/src/components/Bounty.css b/decnet_web/src/components/Bounty.css index a1e37667..22c416aa 100644 --- a/decnet_web/src/components/Bounty.css +++ b/decnet_web/src/components/Bounty.css @@ -19,9 +19,9 @@ cursor: pointer; transition: all 0.3s ease; } -.bounty-root .btn:hover { background: var(--matrix); color: #000; box-shadow: var(--matrix-glow); } +.bounty-root .btn:hover { background: var(--matrix); color: var(--bg); box-shadow: var(--matrix-glow); } .bounty-root .btn.violet { border-color: var(--violet); color: var(--violet); } -.bounty-root .btn.violet:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.bounty-root .btn.violet:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .bounty-root .btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .bounty-root .btn.ghost:hover { opacity: 1; border-color: var(--matrix); background: transparent; box-shadow: var(--matrix-glow); } .bounty-root .btn:disabled { opacity: 0.3; cursor: not-allowed; } diff --git a/decnet_web/src/components/Config.css b/decnet_web/src/components/Config.css index 8f2cff07..95e276bb 100644 --- a/decnet_web/src/components/Config.css +++ b/decnet_web/src/components/Config.css @@ -198,7 +198,7 @@ } .add-user-form select { - background: #0d1117; + background: var(--panel); border: 1px solid var(--border-color); color: var(--text-color); padding: 8px 12px; @@ -213,7 +213,7 @@ } .role-select { - background: #0d1117; + background: var(--panel); border: 1px solid var(--border-color); color: var(--text-color); padding: 4px 8px; diff --git a/decnet_web/src/components/Credentials.css b/decnet_web/src/components/Credentials.css index ec63e8e5..8c76b60b 100644 --- a/decnet_web/src/components/Credentials.css +++ b/decnet_web/src/components/Credentials.css @@ -19,9 +19,9 @@ cursor: pointer; transition: all 0.3s ease; } -.credentials-root .btn:hover { background: var(--matrix); color: #000; box-shadow: var(--matrix-glow); } +.credentials-root .btn:hover { background: var(--matrix); color: var(--bg); box-shadow: var(--matrix-glow); } .credentials-root .btn.violet { border-color: var(--violet); color: var(--violet); } -.credentials-root .btn.violet:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.credentials-root .btn.violet:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .credentials-root .btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .credentials-root .btn.ghost:hover { opacity: 1; border-color: var(--matrix); background: transparent; box-shadow: var(--matrix-glow); } .credentials-root .btn:disabled { opacity: 0.3; cursor: not-allowed; } diff --git a/decnet_web/src/components/DeckyFleet.css b/decnet_web/src/components/DeckyFleet.css index 8648c632..a116eee5 100644 --- a/decnet_web/src/components/DeckyFleet.css +++ b/decnet_web/src/components/DeckyFleet.css @@ -52,11 +52,11 @@ align-items: center; gap: 8px; } -.fleet-root .btn:hover { background: var(--matrix); color: #000; box-shadow: var(--matrix-glow); } +.fleet-root .btn:hover { background: var(--matrix); color: var(--bg); box-shadow: var(--matrix-glow); } .fleet-root .btn.violet { border-color: var(--violet); color: var(--violet); } -.fleet-root .btn.violet:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.fleet-root .btn.violet:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .fleet-root .btn.alert { border-color: var(--alert); color: var(--alert); } -.fleet-root .btn.alert:hover { background: var(--alert); color: #000; box-shadow: 0 0 10px rgba(255, 65, 65, 0.5); } +.fleet-root .btn.alert:hover { background: var(--alert); color: var(--bg); box-shadow: 0 0 10px rgba(255, 65, 65, 0.5); } .fleet-root .btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .fleet-root .btn.ghost:hover { color: var(--matrix); opacity: 1; border-color: var(--matrix); box-shadow: var(--matrix-glow); background: transparent; } .fleet-root .btn.small { padding: 4px 10px; font-size: 0.68rem; } @@ -409,7 +409,7 @@ .tweak-group label { font-size: 0.62rem; opacity: 0.55; letter-spacing: 1.5px; } .input { width: 100%; - background: rgba(0, 0, 0, 0.5); + background: var(--panel); border: 1px solid var(--border); color: var(--matrix); padding: 8px 12px; @@ -422,7 +422,7 @@ .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .code-block { - background: #000; + background: var(--bg); border: 1px solid var(--border); padding: 14px 16px; font-size: 0.75rem; diff --git a/decnet_web/src/components/LiveLogs.css b/decnet_web/src/components/LiveLogs.css index c4b10c2b..41662157 100644 --- a/decnet_web/src/components/LiveLogs.css +++ b/decnet_web/src/components/LiveLogs.css @@ -21,11 +21,11 @@ } .logs-root .btn:hover { background: var(--matrix); - color: #000; + color: var(--bg); box-shadow: var(--matrix-glow); } .logs-root .btn.violet { border-color: var(--violet); color: var(--violet); } -.logs-root .btn.violet:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.logs-root .btn.violet:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .logs-root .btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .logs-root .btn.ghost:hover { opacity: 1; border-color: var(--matrix); background: transparent; box-shadow: var(--matrix-glow); } .logs-root .btn:disabled { opacity: 0.3; cursor: not-allowed; } diff --git a/decnet_web/src/components/MazeNET/Canvas.tsx b/decnet_web/src/components/MazeNET/Canvas.tsx index e9ff65e3..c68becee 100644 --- a/decnet_web/src/components/MazeNET/Canvas.tsx +++ b/decnet_web/src/components/MazeNET/Canvas.tsx @@ -142,10 +142,10 @@ const Canvas = forwardRef(function Canvas( - + - + diff --git a/decnet_web/src/components/MazeNET/MazeNET.css b/decnet_web/src/components/MazeNET/MazeNET.css index 7e8b0014..865a2e19 100644 --- a/decnet_web/src/components/MazeNET/MazeNET.css +++ b/decnet_web/src/components/MazeNET/MazeNET.css @@ -46,7 +46,7 @@ body.maze-fullscreen .maze-shell { gap: 8px; transition: all 0.3s; } -.maze-btn:hover { background: var(--matrix); color: #000; box-shadow: var(--matrix-glow); } +.maze-btn:hover { background: var(--matrix); color: var(--bg); box-shadow: var(--matrix-glow); } .maze-btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .maze-btn.ghost:hover { background: transparent; color: var(--matrix); opacity: 1; @@ -127,14 +127,14 @@ body.maze-fullscreen .maze-shell { /* ── Canvas ─────────────────────────────────── */ .maze-canvas-wrap { - position: relative; background: #000; + position: relative; background: var(--bg); overflow: hidden; user-select: none; height: 100%; min-height: 0; } .maze-pan-layer { position: absolute; inset: 0; will-change: transform; } .maze-grid-bg { position: absolute; inset: 0; - pointer-events: none; opacity: 0.6; overflow: hidden; background: #000; + pointer-events: none; opacity: 0.6; overflow: hidden; background: var(--bg); } .maze-grid-bg svg { display: block; width: 100%; height: 100%; } .maze-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } @@ -372,7 +372,7 @@ body.maze-fullscreen .maze-shell { padding: 30px 10px; font-size: 0.7rem; letter-spacing: 1px; } .maze-diff { - background: #000; border: 1px solid var(--border); + background: var(--bg); border: 1px solid var(--border); padding: 10px 12px; font-size: 0.68rem; line-height: 1.6; white-space: pre; overflow-x: auto; } @@ -562,7 +562,7 @@ body.maze-fullscreen .maze-shell { } .maze-btn.alert:hover { background: var(--alert); - color: #000; + color: var(--bg); box-shadow: 0 0 10px rgba(255, 65, 65, 0.5); opacity: 1; } diff --git a/decnet_web/src/components/ServiceConfigForm.css b/decnet_web/src/components/ServiceConfigForm.css index 4228b2db..fba948a3 100644 --- a/decnet_web/src/components/ServiceConfigForm.css +++ b/decnet_web/src/components/ServiceConfigForm.css @@ -51,7 +51,7 @@ select.svc-cfg-input { font-family: var(--font-mono); font-size: 0.72rem; padding: 4px 6px; - background: rgba(0, 0, 0, 0.35); + background: var(--panel); border: 1px solid var(--border); border-radius: 0; color: var(--matrix); @@ -146,10 +146,10 @@ select.svc-cfg-input { } .svc-cfg-btn:hover:not(:disabled) { background: var(--matrix); - color: #000; + color: var(--bg); } .svc-cfg-btn.violet { border-color: var(--violet); color: var(--violet); } -.svc-cfg-btn.violet:hover:not(:disabled) { background: var(--violet); color: #000; } +.svc-cfg-btn.violet:hover:not(:disabled) { background: var(--violet); color: var(--bg); } .svc-cfg-btn:disabled { opacity: 0.3; cursor: not-allowed; } .svc-cfg-pw-toggle { diff --git a/decnet_web/src/components/Swarm.css b/decnet_web/src/components/Swarm.css index 7b8879ca..bfb37b1f 100644 --- a/decnet_web/src/components/Swarm.css +++ b/decnet_web/src/components/Swarm.css @@ -89,14 +89,14 @@ gap: 8px; } -.control-btn:hover { background: var(--matrix); color: #000; box-shadow: var(--matrix-glow); } +.control-btn:hover { background: var(--matrix); color: var(--bg); box-shadow: var(--matrix-glow); } .control-btn:disabled { opacity: 0.3; cursor: not-allowed; } .control-btn.primary { border-color: var(--violet); color: var(--violet); } -.control-btn.primary:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.control-btn.primary:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .control-btn.danger { border-color: var(--alert, var(--alert)); @@ -104,7 +104,7 @@ } .control-btn.danger:hover { background: var(--alert, var(--alert)); - color: #000; + color: var(--bg); box-shadow: 0 0 10px rgba(255, 77, 77, 0.5); } diff --git a/decnet_web/src/components/TopologyList/CreateTopologyWizard.css b/decnet_web/src/components/TopologyList/CreateTopologyWizard.css index 9957d73c..99c0af8a 100644 --- a/decnet_web/src/components/TopologyList/CreateTopologyWizard.css +++ b/decnet_web/src/components/TopologyList/CreateTopologyWizard.css @@ -162,7 +162,7 @@ } .ctw-field input[type='text'] { padding: 8px 10px; - background: #000; + background: var(--bg); border: 1px solid var(--border, var(--panel-border)); color: var(--text-color); font-family: var(--font-mono); @@ -191,7 +191,7 @@ margin-right: 6px; } .ctw-note code { - background: #000; + background: var(--bg); padding: 1px 5px; font-family: var(--font-mono); color: var(--matrix, #33ff66); @@ -232,7 +232,7 @@ align-items: center; gap: 8px; } -.ctw-btn:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.ctw-btn:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .ctw-btn:disabled { opacity: 0.3; cursor: not-allowed; } .ctw-btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .ctw-btn.ghost:hover { diff --git a/decnet_web/src/components/TopologyList/TopologyList.css b/decnet_web/src/components/TopologyList/TopologyList.css index 1745560c..d4d9c391 100644 --- a/decnet_web/src/components/TopologyList/TopologyList.css +++ b/decnet_web/src/components/TopologyList/TopologyList.css @@ -48,16 +48,16 @@ align-items: center; gap: 8px; } -.tlist-btn:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.tlist-btn:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .tlist-btn:disabled { opacity: 0.3; cursor: not-allowed; } .tlist-btn.ghost { border-color: var(--matrix); color: var(--matrix); } -.tlist-btn.ghost:hover { background: var(--matrix); color: #000; box-shadow: var(--matrix-glow); } +.tlist-btn.ghost:hover { background: var(--matrix); color: var(--bg); box-shadow: var(--matrix-glow); } .tlist-btn.small { padding: 4px 10px; font-size: 0.68rem; } .tlist-btn.danger { border-color: var(--alert, #e74c3c); color: var(--alert, #e74c3c); } -.tlist-btn.danger:hover { background: var(--alert, #e74c3c); color: #000; box-shadow: 0 0 10px rgba(231, 76, 60, 0.5); } +.tlist-btn.danger:hover { background: var(--alert, #e74c3c); color: var(--bg); box-shadow: 0 0 10px rgba(231, 76, 60, 0.5); } .tlist-btn.danger.armed { background: var(--alert, #e74c3c); color: #000; } .tlist-btn.warn { border-color: var(--warn, #e0a040); color: var(--warn, #e0a040); } -.tlist-btn.warn:hover { background: var(--warn, #e0a040); color: #000; box-shadow: 0 0 10px rgba(224, 160, 64, 0.5); } +.tlist-btn.warn:hover { background: var(--warn, #e0a040); color: var(--bg); box-shadow: 0 0 10px rgba(224, 160, 64, 0.5); } .tlist-btn.warn.armed { background: var(--warn, #e0a040); color: #000; } .tlist-create-row { diff --git a/decnet_web/src/components/Webhooks.css b/decnet_web/src/components/Webhooks.css index a6ecb7a4..e6edac02 100644 --- a/decnet_web/src/components/Webhooks.css +++ b/decnet_web/src/components/Webhooks.css @@ -49,15 +49,15 @@ } .webhooks-root .btn:hover { background: var(--matrix); - color: #000; + color: var(--bg); box-shadow: var(--matrix-glow); } .webhooks-root .btn.violet { border-color: var(--violet); color: var(--violet); } -.webhooks-root .btn.violet:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.webhooks-root .btn.violet:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .webhooks-root .btn.alert { border-color: var(--alert, #ff4d4d); color: var(--alert, #ff4d4d); } -.webhooks-root .btn.alert:hover { background: var(--alert, #ff4d4d); color: #000; box-shadow: 0 0 10px rgba(255, 77, 77, 0.5); } +.webhooks-root .btn.alert:hover { background: var(--alert, #ff4d4d); color: var(--bg); box-shadow: 0 0 10px rgba(255, 77, 77, 0.5); } .webhooks-root .btn.warn { border-color: var(--warn, #e0a040); color: var(--warn, #e0a040); } -.webhooks-root .btn.warn:hover { background: var(--warn, #e0a040); color: #000; box-shadow: 0 0 10px rgba(224, 160, 64, 0.5); } +.webhooks-root .btn.warn:hover { background: var(--warn, #e0a040); color: var(--bg); box-shadow: 0 0 10px rgba(224, 160, 64, 0.5); } .webhooks-root .btn.ghost { border-color: var(--border-color); color: var(--matrix); opacity: 0.7; } .webhooks-root .btn.ghost:hover { opacity: 1; border-color: var(--matrix); background: transparent; box-shadow: var(--matrix-glow); } .webhooks-root .btn:disabled { opacity: 0.3; cursor: not-allowed; } @@ -126,7 +126,7 @@ } .webhooks-root .action-btn.fire:hover { background: var(--violet); - color: #000; + color: var(--bg); box-shadow: var(--violet-glow); } @@ -218,7 +218,7 @@ .webhooks-root .wh-form-grid input[type="url"], .webhooks-root .wh-form-grid input[type="password"], .webhooks-root .wh-form-grid textarea { - background: #0d1117; + background: var(--panel); border: 1px solid var(--border-color); color: var(--text-color); padding: 8px 12px; @@ -307,7 +307,7 @@ } .wh-secret-modal .wh-secret-value { - background: #0d1117; + background: var(--panel); border: 1px solid var(--border-color); padding: 10px 12px; font-size: 0.85rem; @@ -336,6 +336,6 @@ transition: all 0.3s ease; } .wh-secret-modal .btn.violet { border-color: var(--violet); color: var(--violet); } -.wh-secret-modal .btn.violet:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.wh-secret-modal .btn.violet:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .wh-secret-modal .btn.ghost { border-color: var(--border-color); color: var(--matrix); opacity: 0.7; } .wh-secret-modal .btn.ghost:hover { opacity: 1; border-color: var(--matrix); background: transparent; box-shadow: var(--matrix-glow); } diff --git a/decnet_web/src/index.css b/decnet_web/src/index.css index bf344e84..d03a86a8 100644 --- a/decnet_web/src/index.css +++ b/decnet_web/src/index.css @@ -172,6 +172,44 @@ html[data-theme="light"] { --accent-glow: none; } +/* Hover behaviour in light mode. + * + * Dark mode hovers fully invert: bg fills with --matrix/--violet/ + * --alert and text becomes --bg. That works on black-cream because + * neon-on-ink has obvious contrast. In light mode that same flip + * lands cream text on near-ink and reads as a jarring colour + * inversion every time the cursor moves. + * + * Light mode therefore tints instead of inverting — hover backgrounds + * use the matching --*-tint-10, text stays in its base colour. + * Targets every common scoped button class via [class*="-btn"] plus + * the unprefixed .btn/button selectors. */ +html[data-theme="light"] + :is(button, .btn, [class*="-btn"]):hover:not(:disabled) { + background: var(--matrix-tint-10); + color: var(--matrix); + box-shadow: none; +} +html[data-theme="light"] + :is(button, .btn, [class*="-btn"]).violet:hover:not(:disabled), +html[data-theme="light"] + :is(button, .btn, [class*="-btn"]).primary:hover:not(:disabled) { + background: var(--violet-tint-10); + color: var(--violet); +} +html[data-theme="light"] + :is(button, .btn, [class*="-btn"]).alert:hover:not(:disabled), +html[data-theme="light"] + :is(button, .btn, [class*="-btn"]).danger:hover:not(:disabled) { + background: var(--alert-tint-10); + color: var(--alert); +} +html[data-theme="light"] + :is(button, .btn, [class*="-btn"]).warn:hover:not(:disabled) { + background: var(--warn-tint-10); + color: var(--warn); +} + *, *::before, *::after { box-sizing: border-box; margin: 0; @@ -220,9 +258,9 @@ button:disabled { /* Shared .btn variants (unscoped) */ .btn.violet { border-color: var(--violet); color: var(--violet); } -.btn.violet:hover { background: var(--violet); color: #000; box-shadow: var(--violet-glow); } +.btn.violet:hover { background: var(--violet); color: var(--bg); box-shadow: var(--violet-glow); } .btn.alert { border-color: var(--alert); color: var(--alert); } -.btn.alert:hover { background: var(--alert); color: #000; box-shadow: 0 0 10px rgba(255, 65, 65, 0.5); } +.btn.alert:hover { background: var(--alert); color: var(--bg); box-shadow: 0 0 10px rgba(255, 65, 65, 0.5); } .btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .btn.ghost:hover { background: transparent; color: var(--matrix); opacity: 1;