fix(decnet_web/css): light-mode contrast across wizards, code blocks, hovers

Sweeps four invariant violations that were leaking dark surfaces
into light mode and producing the unreadable / inverted areas:

  1. Hardcoded `color: #000` in 14 :hover rules across 11 CSS
     files swapped to `color: var(--bg)` — collapses to #000 in
     dark mode (no-op), becomes cream in light. Fixes DEPLOY
     DECKIES (button hover was rendering charcoal-purple text on
     charcoal-purple background).
  2. Hardcoded `background: #000` (3 sites) and `#0d1117`
     (3 sites) replaced with `var(--bg)` / `var(--panel)`. Fixes
     code blocks and modal panels staying dark on cream — the
     deploy-wizard preview, topology-creation NAME input, and the
     MazeNET canvas backdrop now follow the active theme.
  3. `rgba(0,0,0,0.35)` and `rgba(0,0,0,0.5)` input/card
     backgrounds (ServiceConfigForm, DeckyFleet .input)
     swapped to `var(--panel)`. Fixes per-service config rows
     in the deploy wizard rendering as dark slabs.
  4. SVG arrow markers in MazeNET Canvas.tsx hardcoded
     `fill="#00ff41"` / "#ee82ee" — replaced with currentColor +
     style hook so they re-resolve on theme change.

New behaviour: light-mode hovers tint instead of inverting. The
dark-mode rules fully fill bg with --matrix/--violet/--alert and
flip text to --bg; that lands cream-on-near-ink in light mode
and reads as a jarring colour inversion every cursor move. Light
mode now layers a *-tint-10 background and keeps text in its
base colour. Single override block in index.css targets every
scoped `.X-btn`/`.btn`/`button:hover` via :is() + [class*="-btn"]
so we don't have to chase every component file.
This commit is contained in:
2026-05-09 03:43:47 -04:00
parent 34c778277a
commit 11b2da7d54
13 changed files with 81 additions and 43 deletions

View File

@@ -19,9 +19,9 @@
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; 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 { 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 { 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.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; } .bounty-root .btn:disabled { opacity: 0.3; cursor: not-allowed; }

View File

@@ -198,7 +198,7 @@
} }
.add-user-form select { .add-user-form select {
background: #0d1117; background: var(--panel);
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
color: var(--text-color); color: var(--text-color);
padding: 8px 12px; padding: 8px 12px;
@@ -213,7 +213,7 @@
} }
.role-select { .role-select {
background: #0d1117; background: var(--panel);
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
color: var(--text-color); color: var(--text-color);
padding: 4px 8px; padding: 4px 8px;

View File

@@ -19,9 +19,9 @@
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; 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 { 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 { 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.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; } .credentials-root .btn:disabled { opacity: 0.3; cursor: not-allowed; }

View File

@@ -52,11 +52,11 @@
align-items: center; align-items: center;
gap: 8px; 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 { 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 { 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 { 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.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; } .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; } .tweak-group label { font-size: 0.62rem; opacity: 0.55; letter-spacing: 1.5px; }
.input { .input {
width: 100%; width: 100%;
background: rgba(0, 0, 0, 0.5); background: var(--panel);
border: 1px solid var(--border); border: 1px solid var(--border);
color: var(--matrix); color: var(--matrix);
padding: 8px 12px; padding: 8px 12px;
@@ -422,7 +422,7 @@
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.code-block { .code-block {
background: #000; background: var(--bg);
border: 1px solid var(--border); border: 1px solid var(--border);
padding: 14px 16px; padding: 14px 16px;
font-size: 0.75rem; font-size: 0.75rem;

View File

@@ -21,11 +21,11 @@
} }
.logs-root .btn:hover { .logs-root .btn:hover {
background: var(--matrix); background: var(--matrix);
color: #000; color: var(--bg);
box-shadow: var(--matrix-glow); box-shadow: var(--matrix-glow);
} }
.logs-root .btn.violet { border-color: var(--violet); color: var(--violet); } .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 { 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.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; } .logs-root .btn:disabled { opacity: 0.3; cursor: not-allowed; }

View File

@@ -142,10 +142,10 @@ const Canvas = forwardRef<HTMLDivElement, Props>(function Canvas(
<svg className="maze-svg" overflow="visible"> <svg className="maze-svg" overflow="visible">
<defs> <defs>
<marker id="arrow-matrix" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto"> <marker id="arrow-matrix" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0,0 L10,5 L0,10 z" fill="#00ff41" /> <path d="M0,0 L10,5 L0,10 z" fill="currentColor" style={{ color: 'var(--matrix)' }} />
</marker> </marker>
<marker id="arrow-violet" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto"> <marker id="arrow-violet" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0,0 L10,5 L0,10 z" fill="#ee82ee" /> <path d="M0,0 L10,5 L0,10 z" fill="currentColor" style={{ color: 'var(--violet)' }} />
</marker> </marker>
<marker id="arrow-alert" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto"> <marker id="arrow-alert" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
<path d="M0,0 L10,5 L0,10 z" fill="#ff4141" /> <path d="M0,0 L10,5 L0,10 z" fill="#ff4141" />

View File

@@ -46,7 +46,7 @@ body.maze-fullscreen .maze-shell {
gap: 8px; gap: 8px;
transition: all 0.3s; 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 { border-color: var(--border); color: var(--matrix); opacity: 0.7; }
.maze-btn.ghost:hover { .maze-btn.ghost:hover {
background: transparent; color: var(--matrix); opacity: 1; background: transparent; color: var(--matrix); opacity: 1;
@@ -127,14 +127,14 @@ body.maze-fullscreen .maze-shell {
/* ── Canvas ─────────────────────────────────── */ /* ── Canvas ─────────────────────────────────── */
.maze-canvas-wrap { .maze-canvas-wrap {
position: relative; background: #000; position: relative; background: var(--bg);
overflow: hidden; user-select: none; overflow: hidden; user-select: none;
height: 100%; min-height: 0; height: 100%; min-height: 0;
} }
.maze-pan-layer { position: absolute; inset: 0; will-change: transform; } .maze-pan-layer { position: absolute; inset: 0; will-change: transform; }
.maze-grid-bg { .maze-grid-bg {
position: absolute; inset: 0; 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-grid-bg svg { display: block; width: 100%; height: 100%; }
.maze-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } .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; padding: 30px 10px; font-size: 0.7rem; letter-spacing: 1px;
} }
.maze-diff { .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; padding: 10px 12px; font-size: 0.68rem; line-height: 1.6;
white-space: pre; overflow-x: auto; white-space: pre; overflow-x: auto;
} }
@@ -562,7 +562,7 @@ body.maze-fullscreen .maze-shell {
} }
.maze-btn.alert:hover { .maze-btn.alert:hover {
background: var(--alert); background: var(--alert);
color: #000; color: var(--bg);
box-shadow: 0 0 10px rgba(255, 65, 65, 0.5); box-shadow: 0 0 10px rgba(255, 65, 65, 0.5);
opacity: 1; opacity: 1;
} }

View File

@@ -51,7 +51,7 @@ select.svc-cfg-input {
font-family: var(--font-mono); font-family: var(--font-mono);
font-size: 0.72rem; font-size: 0.72rem;
padding: 4px 6px; padding: 4px 6px;
background: rgba(0, 0, 0, 0.35); background: var(--panel);
border: 1px solid var(--border); border: 1px solid var(--border);
border-radius: 0; border-radius: 0;
color: var(--matrix); color: var(--matrix);
@@ -146,10 +146,10 @@ select.svc-cfg-input {
} }
.svc-cfg-btn:hover:not(:disabled) { .svc-cfg-btn:hover:not(:disabled) {
background: var(--matrix); background: var(--matrix);
color: #000; color: var(--bg);
} }
.svc-cfg-btn.violet { border-color: var(--violet); color: var(--violet); } .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-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.svc-cfg-pw-toggle { .svc-cfg-pw-toggle {

View File

@@ -89,14 +89,14 @@
gap: 8px; 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:disabled { opacity: 0.3; cursor: not-allowed; }
.control-btn.primary { .control-btn.primary {
border-color: var(--violet); border-color: var(--violet);
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 { .control-btn.danger {
border-color: var(--alert, var(--alert)); border-color: var(--alert, var(--alert));
@@ -104,7 +104,7 @@
} }
.control-btn.danger:hover { .control-btn.danger:hover {
background: var(--alert, var(--alert)); background: var(--alert, var(--alert));
color: #000; color: var(--bg);
box-shadow: 0 0 10px rgba(255, 77, 77, 0.5); box-shadow: 0 0 10px rgba(255, 77, 77, 0.5);
} }

View File

@@ -162,7 +162,7 @@
} }
.ctw-field input[type='text'] { .ctw-field input[type='text'] {
padding: 8px 10px; padding: 8px 10px;
background: #000; background: var(--bg);
border: 1px solid var(--border, var(--panel-border)); border: 1px solid var(--border, var(--panel-border));
color: var(--text-color); color: var(--text-color);
font-family: var(--font-mono); font-family: var(--font-mono);
@@ -191,7 +191,7 @@
margin-right: 6px; margin-right: 6px;
} }
.ctw-note code { .ctw-note code {
background: #000; background: var(--bg);
padding: 1px 5px; padding: 1px 5px;
font-family: var(--font-mono); font-family: var(--font-mono);
color: var(--matrix, #33ff66); color: var(--matrix, #33ff66);
@@ -232,7 +232,7 @@
align-items: center; align-items: center;
gap: 8px; 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:disabled { opacity: 0.3; cursor: not-allowed; }
.ctw-btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; } .ctw-btn.ghost { border-color: var(--border); color: var(--matrix); opacity: 0.7; }
.ctw-btn.ghost:hover { .ctw-btn.ghost:hover {

View File

@@ -48,16 +48,16 @@
align-items: center; align-items: center;
gap: 8px; 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:disabled { opacity: 0.3; cursor: not-allowed; }
.tlist-btn.ghost { border-color: var(--matrix); color: var(--matrix); } .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.small { padding: 4px 10px; font-size: 0.68rem; }
.tlist-btn.danger { border-color: var(--alert, #e74c3c); color: var(--alert, #e74c3c); } .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.danger.armed { background: var(--alert, #e74c3c); color: #000; }
.tlist-btn.warn { border-color: var(--warn, #e0a040); color: var(--warn, #e0a040); } .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-btn.warn.armed { background: var(--warn, #e0a040); color: #000; }
.tlist-create-row { .tlist-create-row {

View File

@@ -49,15 +49,15 @@
} }
.webhooks-root .btn:hover { .webhooks-root .btn:hover {
background: var(--matrix); background: var(--matrix);
color: #000; color: var(--bg);
box-shadow: var(--matrix-glow); box-shadow: var(--matrix-glow);
} }
.webhooks-root .btn.violet { border-color: var(--violet); color: var(--violet); } .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 { 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 { 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 { 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.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; } .webhooks-root .btn:disabled { opacity: 0.3; cursor: not-allowed; }
@@ -126,7 +126,7 @@
} }
.webhooks-root .action-btn.fire:hover { .webhooks-root .action-btn.fire:hover {
background: var(--violet); background: var(--violet);
color: #000; color: var(--bg);
box-shadow: var(--violet-glow); box-shadow: var(--violet-glow);
} }
@@ -218,7 +218,7 @@
.webhooks-root .wh-form-grid input[type="url"], .webhooks-root .wh-form-grid input[type="url"],
.webhooks-root .wh-form-grid input[type="password"], .webhooks-root .wh-form-grid input[type="password"],
.webhooks-root .wh-form-grid textarea { .webhooks-root .wh-form-grid textarea {
background: #0d1117; background: var(--panel);
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
color: var(--text-color); color: var(--text-color);
padding: 8px 12px; padding: 8px 12px;
@@ -307,7 +307,7 @@
} }
.wh-secret-modal .wh-secret-value { .wh-secret-modal .wh-secret-value {
background: #0d1117; background: var(--panel);
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
padding: 10px 12px; padding: 10px 12px;
font-size: 0.85rem; font-size: 0.85rem;
@@ -336,6 +336,6 @@
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.wh-secret-modal .btn.violet { border-color: var(--violet); color: var(--violet); } .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 { 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); } .wh-secret-modal .btn.ghost:hover { opacity: 1; border-color: var(--matrix); background: transparent; box-shadow: var(--matrix-glow); }

View File

@@ -172,6 +172,44 @@ html[data-theme="light"] {
--accent-glow: none; --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 { *, *::before, *::after {
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
@@ -220,9 +258,9 @@ button:disabled {
/* Shared .btn variants (unscoped) */ /* Shared .btn variants (unscoped) */
.btn.violet { border-color: var(--violet); color: var(--violet); } .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 { 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 { border-color: var(--border); color: var(--matrix); opacity: 0.7; }
.btn.ghost:hover { .btn.ghost:hover {
background: transparent; color: var(--matrix); opacity: 1; background: transparent; color: var(--matrix); opacity: 1;