mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-11-04 11:57:16 +00:00
fix(web_viewer): status and accent text passes contrast in both themes
Bootstrap's text-success, text-warning, text-info and text-danger are fill tones, so used as text they failed contrast (amber on white was 1.6:1, info 2.0:1), and nothing adjusted them for dark mode. base.html now defines per-theme status text tokens that pass 4.5:1 on every surface tier, and the text utilities, text-muted, form-text, code, links and the outline buttons resolve through them. Info and warning badges carry dark text. Ink Muted moves a step darker so it holds on paper-sunk. The dark message bubbles on Realtime were solid navy, forest green and purple, which overpowered the page and dropped the sender names to 1.7:1. They are now low-alpha tints of the signal and lamp hues over the card, like the dashboard delta chips, and the error bubble is red in both themes instead of purple in dark. Also: the light log levels and level toggles move to tones that pass on the log well, the dark ERROR toggle uses dark text, Realtime drops its local orange text-warning and its opacity on message times, and the four copies of the dark .table td * rule no longer force body text color onto badges and buttons. DESIGN.md records the tokens and the rule that a fill hue never goes on text directly.
This commit is contained in:
1 parent
b5bf8c26e2
commit
ebdc44cd90
8 files changed
+146
-45
No files matched your search
@@ -33,7 +33,7 @@
|
||||
--bg-secondary: #f8f9fa;
|
||||
--bg-tertiary: #e9ecef;
|
||||
--text-color: #212529;
|
||||
--text-muted: #6c757d;
|
||||
--text-muted: #5f666d;
|
||||
--border-color: #dee2e6;
|
||||
--card-bg: #ffffff;
|
||||
--card-header-bg: #f8f9fa;
|
||||
@@ -41,6 +41,16 @@
|
||||
--log-entry-bg: #f8f9fa;
|
||||
--connection-info-bg: #e9ecef;
|
||||
--shadow-color: rgba(0, 0, 0, 0.1);
|
||||
/* Status and accent colors used as text. Bootstrap's own text-*
|
||||
colors are background tones and fail contrast as text; these
|
||||
pass 4.5:1 on paper, paper-raised and paper-sunk. */
|
||||
--text-success: #146c43;
|
||||
--text-warning: #7a5d02;
|
||||
--text-danger: #b02a37;
|
||||
--text-info: #0a6c80;
|
||||
--text-primary: #0d6efd;
|
||||
--link-color: #0d6efd;
|
||||
--code-color: #ab296a;
|
||||
}
|
||||
|
||||
/* CSS Variables for Dark Mode */
|
||||
@@ -57,6 +67,14 @@
|
||||
--log-entry-bg: #2d2d2d;
|
||||
--connection-info-bg: #3d3d3d;
|
||||
--shadow-color: rgba(0, 0, 0, 0.3);
|
||||
/* Pass 4.5:1 on night, night-raised and night-sunk. */
|
||||
--text-success: #75b798;
|
||||
--text-warning: #ffda6a;
|
||||
--text-danger: #f1aeb5;
|
||||
--text-info: #6edff6;
|
||||
--text-primary: #6ea8fe;
|
||||
--link-color: #6ea8fe;
|
||||
--code-color: #e685b5;
|
||||
}
|
||||
|
||||
/* Apply theme variables */
|
||||
@@ -255,11 +273,74 @@
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Dark mode text muted */
|
||||
[data-theme="dark"] .text-muted {
|
||||
/* Muted and status text follow the theme in both themes */
|
||||
.text-muted,
|
||||
.form-text {
|
||||
color: var(--text-muted) !important;
|
||||
}
|
||||
|
||||
/* On the console-black table headers and navbar, muted text uses the
|
||||
night tone in either theme. */
|
||||
.table-dark .text-muted,
|
||||
.navbar-dark .text-muted {
|
||||
color: #adb5bd !important;
|
||||
}
|
||||
|
||||
.alert code { color: inherit; }
|
||||
|
||||
.text-success { color: var(--text-success) !important; }
|
||||
.text-warning { color: var(--text-warning) !important; }
|
||||
.text-danger { color: var(--text-danger) !important; }
|
||||
.text-info { color: var(--text-info) !important; }
|
||||
.text-primary { color: var(--text-primary) !important; }
|
||||
code { color: var(--code-color); }
|
||||
|
||||
/* Solid info and warning fills are light, so they carry dark text
|
||||
(Bootstrap 5.1 gives every badge white text). */
|
||||
.badge.bg-info,
|
||||
.badge.bg-warning {
|
||||
color: #212529 !important;
|
||||
}
|
||||
|
||||
[data-theme="dark"] a:not(.btn):not(.nav-link):not(.navbar-brand):not(.dropdown-item) {
|
||||
color: var(--link-color);
|
||||
}
|
||||
|
||||
/* Outline buttons: Bootstrap's outline text colors are its fill tones,
|
||||
which fail as text on raised surfaces and on the dark theme. */
|
||||
.btn-outline-secondary {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.btn-outline-secondary:hover,
|
||||
.btn-outline-secondary.active {
|
||||
color: #fff;
|
||||
background-color: #6c757d;
|
||||
}
|
||||
.btn-outline-danger {
|
||||
color: var(--text-danger);
|
||||
}
|
||||
.btn-outline-danger:hover,
|
||||
.btn-outline-danger.active {
|
||||
color: #fff;
|
||||
}
|
||||
[data-theme="dark"] .btn-outline-primary {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
[data-theme="dark"] .btn-outline-primary:hover,
|
||||
[data-theme="dark"] .btn-outline-primary.active {
|
||||
color: #fff;
|
||||
}
|
||||
.btn-outline-warning {
|
||||
color: var(--text-warning);
|
||||
}
|
||||
.btn-outline-warning:hover,
|
||||
.btn-outline-warning.active {
|
||||
color: #212529;
|
||||
}
|
||||
[data-theme="dark"] .btn-link {
|
||||
color: var(--link-color);
|
||||
}
|
||||
|
||||
/* Dark mode borders. The directional utilities need naming too — the
|
||||
all-sides rule does not cover them, so a .border-start divider drew
|
||||
Bootstrap's light #dee2e6 straight onto a dark card. */
|
||||
|
||||
@@ -2777,9 +2777,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* Ensure all text in table cells is light in dark mode */
|
||||
[data-theme="dark"] .table td,
|
||||
[data-theme="dark"] .table td * {
|
||||
/* Table cells take the light text color in dark mode; children with their
|
||||
own color (badges, buttons, status text) keep it. */
|
||||
[data-theme="dark"] .table td {
|
||||
color: var(--text-color) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -1216,9 +1216,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* Ensure all text in table cells is light in dark mode */
|
||||
[data-theme="dark"] .table td,
|
||||
[data-theme="dark"] .table td * {
|
||||
/* Table cells take the light text color in dark mode; children with their
|
||||
own color (badges, buttons, status text) keep it. */
|
||||
[data-theme="dark"] .table td {
|
||||
color: var(--text-color) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -574,9 +574,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* Ensure all text in table cells is light in dark mode */
|
||||
[data-theme="dark"] .table td,
|
||||
[data-theme="dark"] .table td * {
|
||||
/* Table cells take the light text color in dark mode; children with their
|
||||
own color (badges, buttons, status text) keep it. */
|
||||
[data-theme="dark"] .table td {
|
||||
color: var(--text-color) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,11 @@
|
||||
.log-line.level-error { color: #f85149; }
|
||||
.log-line.level-critical{ color: #ff79c6; font-weight: bold; }
|
||||
|
||||
[data-theme="light"] .log-line.level-debug { color: #0d9488; }
|
||||
[data-theme="light"] .log-line.level-info { color: #0d6efd; }
|
||||
[data-theme="light"] .log-line.level-warning { color: #fd7e14; }
|
||||
[data-theme="light"] .log-line.level-error { color: #dc3545; }
|
||||
/* Light set: each passes 4.5:1 on the light log well (#f8f9fa). */
|
||||
[data-theme="light"] .log-line.level-debug { color: #0f766e; }
|
||||
[data-theme="light"] .log-line.level-info { color: #0a58ca; }
|
||||
[data-theme="light"] .log-line.level-warning { color: #a85300; }
|
||||
[data-theme="light"] .log-line.level-error { color: #b02a37; }
|
||||
[data-theme="light"] .log-line.level-critical{ color: #6610f2; font-weight: bold; }
|
||||
|
||||
.log-controls {
|
||||
@@ -97,14 +98,14 @@
|
||||
.log-level-toggle[data-level="DEBUG"].is-on { background: #2dd4bf; color: #0d1117; border-color: #2dd4bf; }
|
||||
.log-level-toggle[data-level="INFO"].is-on { background: #58a6ff; color: #0d1117; border-color: #58a6ff; }
|
||||
.log-level-toggle[data-level="WARNING"].is-on { background: #d29922; color: #0d1117; border-color: #d29922; }
|
||||
.log-level-toggle[data-level="ERROR"].is-on { background: #f85149; color: #fff; border-color: #f85149; }
|
||||
.log-level-toggle[data-level="ERROR"].is-on { background: #f85149; color: #0d1117; border-color: #f85149; }
|
||||
.log-level-toggle[data-level="CRITICAL"].is-on { background: #ff79c6; color: #0d1117; border-color: #ff79c6; }
|
||||
|
||||
/* Light theme — on */
|
||||
[data-theme="light"] .log-level-toggle[data-level="DEBUG"].is-on { background: #0d9488; color: #fff; border-color: #0d9488; }
|
||||
[data-theme="light"] .log-level-toggle[data-level="INFO"].is-on { background: #0d6efd; color: #fff; border-color: #0d6efd; }
|
||||
[data-theme="light"] .log-level-toggle[data-level="DEBUG"].is-on { background: #0f766e; color: #fff; border-color: #0f766e; }
|
||||
[data-theme="light"] .log-level-toggle[data-level="INFO"].is-on { background: #0a58ca; color: #fff; border-color: #0a58ca; }
|
||||
[data-theme="light"] .log-level-toggle[data-level="WARNING"].is-on { background: #fd7e14; color: #212529; border-color: #fd7e14; }
|
||||
[data-theme="light"] .log-level-toggle[data-level="ERROR"].is-on { background: #dc3545; color: #fff; border-color: #dc3545; }
|
||||
[data-theme="light"] .log-level-toggle[data-level="ERROR"].is-on { background: #b02a37; color: #fff; border-color: #b02a37; }
|
||||
[data-theme="light"] .log-level-toggle[data-level="CRITICAL"].is-on { background: #6610f2; color: #fff; border-color: #6610f2; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1968,9 +1968,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* Ensure all text in table cells is light in dark mode */
|
||||
[data-theme="dark"] .table td,
|
||||
[data-theme="dark"] .table td * {
|
||||
/* Table cells take the light text color in dark mode; children with their
|
||||
own color (badges, buttons, status text) keep it. */
|
||||
[data-theme="dark"] .table td {
|
||||
color: var(--text-color) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
.live-msg-time {
|
||||
font-size: 0.58rem;
|
||||
line-height: 1.2;
|
||||
opacity: 0.88;
|
||||
}
|
||||
|
||||
.stream-entry:hover {
|
||||
@@ -162,10 +161,6 @@
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #fd7e14 !important;
|
||||
}
|
||||
|
||||
.conversation-entry {
|
||||
border-left: 3px solid #007bff;
|
||||
padding-left: 10px;
|
||||
@@ -179,11 +174,23 @@
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* Dark bubbles are light tints of the lamp and signal hues over the
|
||||
card, like the dashboard delta chips, so body text and the theme's
|
||||
status text colors keep their contrast inside them. */
|
||||
[data-theme="dark"] .user-message {
|
||||
background-color: #1a237e;
|
||||
border-color: #283593;
|
||||
color: #e3f2fd;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
||||
background-color: rgba(13, 110, 253, 0.18);
|
||||
border-color: rgba(110, 168, 254, 0.35);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
/* Sender names on the light blue bubble need a deeper blue than the
|
||||
page's link blue. */
|
||||
.user-message .text-primary {
|
||||
color: #0a58ca !important;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .user-message .text-primary {
|
||||
color: #8bb9fe !important;
|
||||
}
|
||||
|
||||
.bot-message-success {
|
||||
@@ -194,10 +201,9 @@
|
||||
}
|
||||
|
||||
[data-theme="dark"] .bot-message-success {
|
||||
background-color: #1b5e20;
|
||||
border-color: #2e7d32;
|
||||
color: #c8e6c9;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
||||
background-color: rgba(25, 135, 84, 0.2);
|
||||
border-color: rgba(117, 183, 152, 0.35);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.bot-message-danger {
|
||||
@@ -208,10 +214,9 @@
|
||||
}
|
||||
|
||||
[data-theme="dark"] .bot-message-danger {
|
||||
background-color: #4a148c;
|
||||
border-color: #6a1b9a;
|
||||
color: #f8bbd0;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
|
||||
background-color: rgba(220, 53, 69, 0.18);
|
||||
border-color: rgba(234, 134, 143, 0.35);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.response-text {
|
||||
@@ -529,15 +534,15 @@
|
||||
<small class="text-muted me-1">Show:</small>
|
||||
<div class="form-check form-check-inline mb-0">
|
||||
<input class="form-check-input rt-filter-cb" type="checkbox" id="rt-filter-command" data-target="command-card" checked>
|
||||
<label class="form-check-label" for="rt-filter-command" style="font-size:0.8rem;color:#6c757d">Commands</label>
|
||||
<label class="form-check-label text-muted" for="rt-filter-command" style="font-size:0.8rem">Commands</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline mb-0">
|
||||
<input class="form-check-input rt-filter-cb" type="checkbox" id="rt-filter-packet" data-target="packet-card" checked>
|
||||
<label class="form-check-label" for="rt-filter-packet" style="font-size:0.8rem;color:#0dcaf0">Packets</label>
|
||||
<label class="form-check-label text-info" for="rt-filter-packet" style="font-size:0.8rem">Packets</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline mb-0">
|
||||
<input class="form-check-input rt-filter-cb" type="checkbox" id="rt-filter-message" data-target="message-card" checked>
|
||||
<label class="form-check-label" for="rt-filter-message" style="font-size:0.8rem;color:#0d6efd">Messages</label>
|
||||
<label class="form-check-label text-primary" for="rt-filter-message" style="font-size:0.8rem">Messages</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user