Merge branch 'master' of git.wrede.ca:andreas/heartbeat

This commit is contained in:
2026-06-01 07:56:02 -04:00
20 changed files with 1117 additions and 49 deletions
+13
View File
@@ -100,6 +100,19 @@
}
.logo-text { flex: 1; }
/* ── Dark mode ── */
html[data-theme="dark"] h1 { color: var(--text); }
html[data-theme="dark"] .subtitle { color: var(--text-sec); }
html[data-theme="dark"] .section { background: var(--surface); box-shadow: 0 1px 6px var(--shadow); }
html[data-theme="dark"] .section h2 { color: var(--text); border-bottom-color: var(--border); }
html[data-theme="dark"] .info-row { border-bottom-color: var(--border-4); }
html[data-theme="dark"] .info-label { color: var(--text-sec); }
html[data-theme="dark"] .info-value { color: var(--text); }
html[data-theme="dark"] .info-value a { color: var(--link); }
html[data-theme="dark"] .hb-logo { color: var(--link); }
html[data-theme="dark"] .hb-tagline { color: var(--text-sec); }
html[data-theme="dark"] .version-badge { background: #1a3255; color: #60a5fa; }
</style>
<body>
+25
View File
@@ -305,6 +305,31 @@
text-align: right;
margin-bottom: 15px;
}
/* ── Dark mode ── */
html[data-theme="dark"] h1 { color: var(--text); }
html[data-theme="dark"] .subtitle { color: var(--text-sec); }
html[data-theme="dark"] .summary-card { background: var(--surface); }
html[data-theme="dark"] .summary-label { color: var(--text-sec); }
html[data-theme="dark"] .filters { background: var(--surface); }
html[data-theme="dark"] .filter-label { color: var(--text-sec); }
html[data-theme="dark"] .filter-button { background: var(--surface-2); border-color: var(--border); color: var(--text); }
html[data-theme="dark"] .filter-button.active { background: #2196f3; color: #fff; border-color: #2196f3; }
html[data-theme="dark"] .filter-input { background: var(--input-bg); border-color: var(--input-border); color: var(--text); }
html[data-theme="dark"] .alerts-container { background: var(--surface); }
html[data-theme="dark"] .alert-item { background: var(--surface-2); }
html[data-theme="dark"] .alert-item.acknowledged { background: var(--surface-3); }
html[data-theme="dark"] .alert-item.critical { background: #2e0a0a; border-left-color: #f44336; }
html[data-theme="dark"] .alert-item.warning { background: #2e1a00; border-left-color: #ff9800; }
html[data-theme="dark"] .alert-item.unknown { background: var(--surface-2); }
html[data-theme="dark"] .alert-hostname { color: var(--link); }
html[data-theme="dark"] .alert-details { color: var(--text-sec); }
html[data-theme="dark"] .alert-value { color: var(--text); }
html[data-theme="dark"] .alert-duration { color: var(--text-muted); }
html[data-theme="dark"] .last-update { color: var(--text-sec); }
html[data-theme="dark"] .refresh-info { color: var(--text-muted); border-top-color: var(--border); }
html[data-theme="dark"] .no-alerts,
html[data-theme="dark"] .loading { color: var(--text-muted); }
</style>
<body>
+94 -12
View File
@@ -5,7 +5,68 @@
<link rel="icon" href="/static/images/favicon.ico" sizes="32x32" />
<title>{{ title }}</title>
{% if extra_scripts %}<script src="{{ extra_scripts }}"></script>{% endif %}
<script>
/* Apply saved theme before first paint to avoid flash */
(function() {
try {
var p = localStorage.getItem('hbd_theme') || 'auto';
var dark = p === 'dark' || (p === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
if (dark) document.documentElement.setAttribute('data-theme', 'dark');
} catch(e) {}
})();
</script>
<style>
/* ── Theme variables ── */
:root {
--bg: #f5f5f5;
--surface: #ffffff;
--surface-2: #f8f8f8;
--surface-3: #f5f5f5;
--text: #222222;
--text-2: #333333;
--text-3: #555555;
--text-sec: #666666;
--text-muted: #888888;
--text-dim: #aaaaaa;
--text-ghost: #cccccc;
--border: #e0e0e0;
--border-2: #eeeeee;
--border-3: #f0f0f0;
--border-4: #f5f5f5;
--link: #0066cc;
--nav-bg: #ffffff;
--input-bg: #ffffff;
--input-border: #cccccc;
--shadow-sm: rgba(0,0,0,.08);
--shadow: rgba(0,0,0,.10);
--shadow-nav: rgba(0,0,0,.10);
}
html[data-theme="dark"] {
color-scheme: dark;
--bg: #111827;
--surface: #1f2937;
--surface-2: #283447;
--surface-3: #374151;
--text: #e5e7eb;
--text-2: #d1d5db;
--text-3: #9ca3af;
--text-sec: #9ca3af;
--text-muted: #6b7280;
--text-dim: #4b5563;
--text-ghost: #374151;
--border: #374151;
--border-2: #2d3748;
--border-3: #253040;
--border-4: #1e2a38;
--link: #60a5fa;
--nav-bg: #1f2937;
--input-bg: #283447;
--input-border: #4b5563;
--shadow-sm: rgba(0,0,0,.30);
--shadow: rgba(0,0,0,.40);
--shadow-nav: rgba(0,0,0,.40);
}
/* ── Reset / shared baseline ── */
*, *::before, *::after { box-sizing: border-box; }
html {
@@ -16,10 +77,11 @@
margin: 0;
padding: 10px;
padding-top: 60px;
background: #f5f5f5;
background: var(--bg);
color: var(--text);
}
h1 { font-size: 1.5em; color: #333; margin: 0 0 5px; }
h2 { font-size: 1.1em; color: #333; margin: 0 0 8px; }
h1 { font-size: 1.5em; color: var(--text-2); margin: 0 0 5px; }
h2 { font-size: 1.1em; color: var(--text-2); margin: 0 0 8px; }
p { margin: 0; }
/* Navigation bar — shared across all pages */
@@ -29,9 +91,9 @@
left: 0;
right: 0;
z-index: 200;
background: #fff;
background: var(--nav-bg);
padding: 6px 12px;
box-shadow: 0 2px 4px rgba(0,0,0,.1);
box-shadow: 0 2px 4px var(--shadow-nav);
display: flex;
align-items: center;
justify-content: space-between;
@@ -42,25 +104,25 @@
.nav a {
margin-right: 20px;
text-decoration: none;
color: #0066cc;
color: var(--link);
font-weight: 500;
font-size: 0.9em;
}
.nav a:hover { text-decoration: underline; }
.nav a.active { color: #333; font-weight: bold; }
.nav a.active { color: var(--text-2); font-weight: bold; }
.nav-user {
display: flex;
align-items: center;
gap: 8px;
text-decoration: none;
color: #333;
color: var(--text-2);
font-size: 0.9em;
font-weight: 500;
padding: 4px 8px;
border-radius: 20px;
transition: background 0.15s;
}
.nav-user:hover { background: #f0f4ff; text-decoration: none; }
.nav-user:hover { background: var(--surface-2); text-decoration: none; }
.nav-username {
max-width: 0;
overflow: hidden;
@@ -81,7 +143,7 @@
.nav-initials {
width: 28px; height: 28px;
border-radius: 50%;
background: #0066cc;
background: var(--link);
color: #fff;
display: flex;
align-items: center;
@@ -106,7 +168,7 @@
.nav-hamburger span {
display: block;
height: 3px;
background: #555;
background: var(--text-muted);
border-radius: 2px;
}
@@ -118,13 +180,22 @@
flex-direction: column;
align-items: flex-start;
padding-top: 8px;
border-top: 1px solid #eee;
border-top: 1px solid var(--border-2);
order: 3;
}
.nav-links.nav-open { display: flex; }
.nav-links a { margin-right: 0; padding: 6px 0; font-size: 1em; }
}
/* ── Global dark-mode: inputs ── */
html[data-theme="dark"] input:not([type=checkbox]):not([type=radio]),
html[data-theme="dark"] select,
html[data-theme="dark"] textarea {
background-color: var(--input-bg);
border-color: var(--input-border);
color: var(--text);
}
/* Pending config publish button */
.nav-publish-btn {
background: #e65100;
@@ -279,6 +350,17 @@
setTimeout(clockTick, delay);
}
/* Keep auto-theme in sync with system setting changes */
try {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
var pref = localStorage.getItem('hbd_theme') || 'auto';
if (pref === 'auto') {
if (e.matches) { document.documentElement.setAttribute('data-theme', 'dark'); }
else { document.documentElement.removeAttribute('data-theme'); }
}
});
} catch(e) {}
document.addEventListener('DOMContentLoaded', function() {
/* Start the shared tick loop */
clockTick();
+26 -1
View File
@@ -288,6 +288,31 @@
}
#ntable a.host-link { color: inherit; text-decoration: none; }
#ntable a.host-link:hover { text-decoration: underline; }
/* ── Dark mode ── */
html[data-theme="dark"] h1,
html[data-theme="dark"] h2 { color: var(--text); }
html[data-theme="dark"] .subtitle { color: var(--text-sec); }
html[data-theme="dark"] h2,
html[data-theme="dark"] .table-section,
html[data-theme="dark"] .log-section,
html[data-theme="dark"] .log-section-header { background: var(--surface); }
html[data-theme="dark"] .log-section-title { color: var(--text); }
html[data-theme="dark"] #ntable td,
html[data-theme="dark"] #ntable th { border-color: var(--border); }
html[data-theme="dark"] #ntable tr:nth-child(even) { background: var(--surface-2); }
html[data-theme="dark"] #ntable tr:hover { background: #1e3a5f; }
html[data-theme="dark"] #ntable tbody tr.row-warning { background: #3a2800; }
html[data-theme="dark"] #ntable tbody tr.row-critical { background: #3a0a0a; }
html[data-theme="dark"] #ntable tbody tr.row-warning:hover { background: #4a3200; }
html[data-theme="dark"] #ntable tbody tr.row-critical:hover { background: #4a1010; }
html[data-theme="dark"] #messages .log-entry { border-bottom-color: var(--border-3); }
html[data-theme="dark"] .log-ts,
html[data-theme="dark"] .log-service { color: var(--text-muted); }
html[data-theme="dark"] .log-info .log-level { color: var(--text-sec); }
html[data-theme="dark"] .log-filter-bar input,
html[data-theme="dark"] .log-filter-bar select { color: var(--text); }
html[data-theme="dark"] .connection-modal-content { background: var(--surface); color: var(--text); }
</style>
<script type="text/javascript">
var cnt = 0;
@@ -540,7 +565,7 @@
if (msg.service) html += '<span class="log-service">' + msg.service + '</span>';
html += '<span class="log-msg">' + msg.message + '</span>';
html += '</div>';
msgs.insertAdjacentHTML("afterbegin", html);
msgs.insertAdjacentHTML(state.history ? "beforeend" : "afterbegin", html);
applyLogFilters();
}
cnt++;
+41
View File
@@ -412,6 +412,47 @@
.info-note { color: #888; font-style: italic; }
.info-loading { color: #bbb; font-style: italic; }
.threshold-covers { font-size: 1.00em; color: #777; font-style: italic; }
/* ── Dark mode ── */
html[data-theme="dark"] h1 { color: var(--text); }
html[data-theme="dark"] .subtitle { color: var(--text-sec); }
html[data-theme="dark"] .host-card { background: var(--surface); }
html[data-theme="dark"] .host-header:hover { background: var(--surface-2); }
html[data-theme="dark"] .host-name { color: var(--text); }
html[data-theme="dark"] .collapse-icon,
html[data-theme="dark"] .acc-icon { color: var(--text-muted); }
html[data-theme="dark"] .host-body { border-top-color: var(--border-3); }
html[data-theme="dark"] .plugin-accordion { border-color: var(--border); }
html[data-theme="dark"] .plugin-acc-header { background: var(--surface-2); }
html[data-theme="dark"] .plugin-acc-header:hover { background: var(--surface-3); }
html[data-theme="dark"] .plugin-label { color: var(--text-2); }
html[data-theme="dark"] .plugin-summary { color: var(--text-muted); }
html[data-theme="dark"] .data-table { background: var(--surface); }
html[data-theme="dark"] .data-table td { border-top-color: var(--border); color: var(--text); }
html[data-theme="dark"] .data-table td.key { color: var(--text-sec); }
html[data-theme="dark"] .data-table tbody tr:nth-child(even) { background: var(--surface-2); }
html[data-theme="dark"] .data-table tbody tr:hover { background: #1e3a5f; }
html[data-theme="dark"] .bar-track { background: var(--border); }
html[data-theme="dark"] .table-section-label { color: var(--text-muted); }
html[data-theme="dark"] .no-data,
html[data-theme="dark"] .loading { color: var(--text-dim); }
html[data-theme="dark"] .timestamp { color: var(--text-dim); border-top-color: var(--border-3); }
html[data-theme="dark"] .glance-chip.neutral { background: var(--surface-3); color: var(--text-sec); }
html[data-theme="dark"] .os-label { color: var(--text-muted); }
html[data-theme="dark"] .host-info-section { background: var(--surface-2); border-bottom-color: var(--border); }
html[data-theme="dark"] .info-label { color: var(--text-3); }
html[data-theme="dark"] .info-value { color: var(--text); }
html[data-theme="dark"] .info-thresholds-title { color: var(--text-3); }
html[data-theme="dark"] .info-note,
html[data-theme="dark"] .info-loading,
html[data-theme="dark"] .threshold-covers { color: var(--text-muted); }
html[data-theme="dark"] .check-ok { background: #0d2e17; }
html[data-theme="dark"] .check-warning { background: #2e1a00; }
html[data-theme="dark"] .check-critical { background: #2e0a0a; }
html[data-theme="dark"] .check-unknown { background: var(--surface-2); }
html[data-theme="dark"] .check-output { color: var(--text-sec); }
html[data-theme="dark"] .container::-webkit-scrollbar-track { background: var(--surface-2); }
html[data-theme="dark"] .container::-webkit-scrollbar-thumb { background: var(--border); }
</style>
<body>
+85
View File
@@ -247,6 +247,56 @@
.btn-sm-del { background: transparent; color: #c62828; border: 1px solid #e0e0e0; border-radius: 4px; padding: 2px 7px; font-size: .78em; cursor: pointer; }
.btn-sm-del:hover { background: #fce4ec; }
/* ---- Theme picker ---- */
.theme-btns { display: flex; gap: 6px; }
.theme-btn {
padding: 5px 14px;
border: 1px solid var(--border, #e0e0e0);
border-radius: 4px;
background: var(--surface-3, #f5f5f5);
color: var(--text-sec, #666);
cursor: pointer;
font-size: .88em;
font-family: inherit;
}
.theme-btn:hover { border-color: var(--link, #0066cc); color: var(--link, #0066cc); }
.theme-btn.active { background: var(--link, #0066cc); color: #fff; border-color: var(--link, #0066cc); }
/* ── Dark mode ── */
html[data-theme="dark"] h1 { color: var(--text); }
html[data-theme="dark"] .subtitle { color: var(--text-sec); }
html[data-theme="dark"] .profile-card { background: var(--surface); box-shadow: 0 1px 6px var(--shadow); }
html[data-theme="dark"] .profile-name { color: var(--text); }
html[data-theme="dark"] .profile-username { color: var(--text-sec); }
html[data-theme="dark"] .badge-admin { background: #1a3255; color: #7aa8f0; }
html[data-theme="dark"] .badge-user { background: var(--surface-3); color: var(--text-sec); }
html[data-theme="dark"] .section { background: var(--surface); box-shadow: 0 1px 6px var(--shadow); }
html[data-theme="dark"] .section h2 { color: var(--text); border-bottom-color: var(--border); }
html[data-theme="dark"] .settings-row { border-bottom-color: var(--border-4); }
html[data-theme="dark"] .settings-label { color: var(--text-sec); }
html[data-theme="dark"] .settings-value { color: var(--text); }
html[data-theme="dark"] .settings-empty { color: var(--text-dim); }
html[data-theme="dark"] .edit-section h4 { color: var(--text); border-bottom-color: var(--border); }
html[data-theme="dark"] .edit-field label { color: var(--text-sec); }
html[data-theme="dark"] .edit-input { background: var(--input-bg); border-color: var(--input-border); color: var(--text); }
html[data-theme="dark"] .channel-row { border-bottom-color: var(--border-4); }
html[data-theme="dark"] .channel-name { color: var(--text); }
html[data-theme="dark"] .ch-picker-label { color: var(--text-sec); }
html[data-theme="dark"] .ch-chip.selected { background: #1a3255; color: #60a5fa; }
html[data-theme="dark"] .ch-chip.available { background: var(--surface-3); color: var(--text-sec); }
html[data-theme="dark"] .ch-chip.available:hover { background: var(--border); color: var(--link); }
html[data-theme="dark"] .my-ch-card { border-color: var(--border); }
html[data-theme="dark"] .my-ch-header { background: var(--surface-2); border-bottom-color: var(--border); }
html[data-theme="dark"] .my-ch-name { color: var(--text); }
html[data-theme="dark"] .host-chip.owner { background: #0d2e17; color: #66bb6a; }
html[data-theme="dark"] .host-chip.manager { background: #0d1f40; color: #64b5f6; }
html[data-theme="dark"] .host-chip.monitor { background: #1e0d30; color: #ba68c8; }
html[data-theme="dark"] .no-hosts { color: var(--text-dim); }
html[data-theme="dark"] .ch-modal-box { background: var(--surface); color: var(--text); }
html[data-theme="dark"] .ch-modal-box h3 { color: var(--text); }
html[data-theme="dark"] .ch-form-row label { color: var(--text-sec); }
html[data-theme="dark"] .ch-form-divider { color: var(--text-muted); border-top-color: var(--border); }
/* ---- Channel modal (for My Channels CRUD) ---- */
.ch-modal-overlay {
position: fixed; inset: 0; background: rgba(0,0,0,.4);
@@ -477,6 +527,19 @@
</div>
{% endif %}
<!-- Appearance -->
<div class="section">
<h2>Appearance</h2>
<div class="settings-row">
<span class="settings-label">Theme</span>
<div class="theme-btns">
<button class="theme-btn" data-theme-val="auto" onclick="setTheme('auto')">Auto</button>
<button class="theme-btn" data-theme-val="light" onclick="setTheme('light')">Light</button>
<button class="theme-btn" data-theme-val="dark" onclick="setTheme('dark')">Dark</button>
</div>
</div>
</div>
<!-- Host access -->
<div class="section">
<h2>Host Access</h2>
@@ -523,6 +586,28 @@
</div>
<script>
// ---- Theme ----
function applyTheme(pref) {
var dark = pref === 'dark' ||
(pref === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches);
if (dark) { document.documentElement.setAttribute('data-theme', 'dark'); }
else { document.documentElement.removeAttribute('data-theme'); }
}
function setTheme(pref) {
try { localStorage.setItem('hbd_theme', pref); } catch(e) {}
applyTheme(pref);
document.querySelectorAll('.theme-btn').forEach(function(b) {
b.classList.toggle('active', b.dataset.themeVal === pref);
});
}
(function() {
var pref = 'auto';
try { pref = localStorage.getItem('hbd_theme') || 'auto'; } catch(e) {}
document.querySelectorAll('.theme-btn').forEach(function(b) {
b.classList.toggle('active', b.dataset.themeVal === pref);
});
})();
// ---- Identity ----
async function saveIdentity() {
const full_name = document.getElementById('profile-fullname').value;
+61
View File
@@ -456,6 +456,67 @@
display: flex; justify-content: flex-end; background: #f8f8f8;
}
.mpick-none { padding: 10px; font-size: .82em; color: #aaa; text-align: center; }
/* ── Dark mode ── */
html[data-theme="dark"] h1 { color: var(--text); }
html[data-theme="dark"] .subtitle { color: var(--text-sec); }
html[data-theme="dark"] .sidebar-nav a { color: var(--text-sec); }
html[data-theme="dark"] .sidebar-nav a:hover { background: var(--surface-3); color: var(--link); }
html[data-theme="dark"] .sidebar-nav a.active { background: #1a3255; color: #60a5fa; }
html[data-theme="dark"] .sidebar-toggle { background: var(--surface-3); color: var(--text-sec); }
html[data-theme="dark"] .sidebar-nav { background: var(--surface); }
html[data-theme="dark"] .section { background: var(--surface); box-shadow: 0 1px 4px var(--shadow); }
html[data-theme="dark"] .section-header { border-bottom-color: var(--border); }
html[data-theme="dark"] .section-title { color: var(--text-2); }
html[data-theme="dark"] .section-desc { color: var(--text-muted); }
html[data-theme="dark"] .section-footer { border-top-color: var(--border-3); }
html[data-theme="dark"] .field-row { border-bottom-color: var(--border-4); }
html[data-theme="dark"] .field-label { color: var(--text-sec); }
html[data-theme="dark"] .field-value { color: var(--text); }
html[data-theme="dark"] .field-desc { color: var(--text-muted); }
html[data-theme="dark"] .val-boolean.on { background: #0d2e17; color: #66bb6a; }
html[data-theme="dark"] .val-boolean.off { background: #2e0d0d; color: #ef9a9a; }
html[data-theme="dark"] .val-tag { background: #1a2d5a; color: #7aa8f0; }
html[data-theme="dark"] .val-empty { color: var(--text-dim); }
html[data-theme="dark"] .val-masked { color: var(--text-muted); }
html[data-theme="dark"] .mini-table th { background: var(--surface-3); color: var(--text-sec); border-bottom-color: var(--border); }
html[data-theme="dark"] .mini-table td { border-bottom-color: var(--border-3); color: var(--text); }
html[data-theme="dark"] .mini-table tbody tr:hover { background: var(--surface-2); }
html[data-theme="dark"] .badge-admin { background: #1a3255; color: #7aa8f0; }
html[data-theme="dark"] .badge-user { background: var(--surface-3); color: var(--text-sec); }
html[data-theme="dark"] .channel-card { border-color: var(--border); }
html[data-theme="dark"] .channel-header { background: var(--surface-2); border-bottom-color: var(--border); }
html[data-theme="dark"] .channel-name-text { color: var(--text); }
html[data-theme="dark"] .channel-field { border-bottom-color: var(--border-4); }
html[data-theme="dark"] .channel-field-label { color: var(--text-muted); }
html[data-theme="dark"] .channel-field-value { color: var(--text); }
html[data-theme="dark"] .thresh-cfg-card { border-color: var(--border); }
html[data-theme="dark"] .thresh-cfg-header { background: var(--surface-2); border-bottom-color: var(--border); }
html[data-theme="dark"] .thresh-cfg-name-label { color: #60a5fa; }
html[data-theme="dark"] .crud-table th { background: var(--surface-3); color: var(--text-sec); border-bottom-color: var(--border); }
html[data-theme="dark"] .crud-table td { border-bottom-color: var(--border-3); color: var(--text); }
html[data-theme="dark"] .yaml-editor { background: var(--input-bg); border-color: var(--input-border); color: var(--text); }
html[data-theme="dark"] .pending-banner { background: #2d2400; border-color: #a08020; }
html[data-theme="dark"] .pending-banner .pending-msg { color: #e8c840; }
html[data-theme="dark"] .modal-box,
html[data-theme="dark"] .ch-modal-box { background: var(--surface); color: var(--text); }
html[data-theme="dark"] .modal-box h3,
html[data-theme="dark"] .ch-modal-box h3 { color: var(--text); }
html[data-theme="dark"] .ch-form-row label { color: var(--text-sec); }
html[data-theme="dark"] .ch-form-divider { color: var(--text-muted); border-top-color: var(--border); }
html[data-theme="dark"] .backup-row { border-bottom-color: var(--border-3); }
html[data-theme="dark"] .mpick-display { background: var(--input-bg); border-color: var(--input-border); }
html[data-theme="dark"] .mpick-display:hover { border-color: var(--link); background: var(--surface-2); }
html[data-theme="dark"] .mpick-tag { background: #1a2d5a; color: #7aa8f0; }
html[data-theme="dark"] .mpick-more,
html[data-theme="dark"] .mpick-empty { color: var(--text-muted); }
html[data-theme="dark"] .mpick-panel { background: var(--surface); border-color: var(--border); }
html[data-theme="dark"] .mpick-panel-header { background: var(--surface-3); color: var(--text-sec); border-bottom-color: var(--border); }
html[data-theme="dark"] .mpick-item { border-bottom-color: var(--border-4); color: var(--text); }
html[data-theme="dark"] .mpick-item-avail:hover { background: #0d2e17; }
html[data-theme="dark"] .mpick-item-sel:hover { background: #2e0d0d; }
html[data-theme="dark"] .mpick-panel-footer { background: var(--surface-2); border-top-color: var(--border); }
html[data-theme="dark"] .mpick-none { color: var(--text-dim); }
</style>
<body>