Refactor front-end assets into external modules (#245)

* Refactor front-end assets into external modules

* Restore chat flag inline script

* Declare legend toggle control variable

* Remove dynamic background generation

* Restore background script with theme-based color

* run rufo
This commit is contained in:
l5y
2025-10-07 08:33:06 +02:00
committed by GitHub
parent 6660986211
commit 64f8862676
8 changed files with 3593 additions and 3018 deletions
+38
View File
@@ -49,6 +49,22 @@ MAX_JSON_BODY_BYTES = begin
end
# Fallback version string used when Git metadata is unavailable.
VERSION_FALLBACK = "v0.3.0"
DEFAULT_REFRESH_INTERVAL_SECONDS = 60
REFRESH_INTERVAL_SECONDS = begin
raw = ENV.fetch("REFRESH_INTERVAL_SECONDS", DEFAULT_REFRESH_INTERVAL_SECONDS.to_s)
value = Integer(raw, 10)
value.positive? ? value : DEFAULT_REFRESH_INTERVAL_SECONDS
rescue ArgumentError
DEFAULT_REFRESH_INTERVAL_SECONDS
end
MAP_TILE_FILTER_LIGHT = ENV.fetch(
"MAP_TILE_FILTER_LIGHT",
"grayscale(1) saturate(0) brightness(0.92) contrast(1.05)"
)
MAP_TILE_FILTER_DARK = ENV.fetch(
"MAP_TILE_FILTER_DARK",
"grayscale(1) invert(1) brightness(0.9) contrast(1.08)"
)
# Fetch a configuration string from environment variables.
#
@@ -162,6 +178,25 @@ def sanitized_default_frequency
sanitized_string(DEFAULT_FREQUENCY)
end
# Assemble configuration exposed to the frontend JavaScript bundle.
#
# @return [Hash] settings describing refresh cadence and map defaults.
def frontend_app_config
{
refreshIntervalSeconds: REFRESH_INTERVAL_SECONDS,
refreshMs: REFRESH_INTERVAL_SECONDS * 1000,
chatEnabled: !private_mode?,
defaultChannel: sanitized_default_channel,
defaultFrequency: sanitized_default_frequency,
mapCenter: { lat: MAP_CENTER_LAT, lon: MAP_CENTER_LON },
maxNodeDistanceKm: MAX_NODE_DISTANCE_KM,
tileFilters: {
light: MAP_TILE_FILTER_LIGHT,
dark: MAP_TILE_FILTER_DARK,
},
}
end
# Return the configured Matrix room when present.
#
# @return [String, nil] Matrix room identifier or nil when blank.
@@ -1919,6 +1954,7 @@ end
# Renders the main site with configuration-driven defaults for the template.
get "/" do
meta = meta_configuration
config = frontend_app_config
response.set_cookie("theme", value: "dark", path: "/", max_age: 60 * 60 * 24 * 7, same_site: :lax) unless request.cookies["theme"]
@@ -1935,5 +1971,7 @@ get "/" do
matrix_room: sanitized_matrix_room,
version: APP_VERSION,
private_mode: private_mode?,
refresh_interval_seconds: REFRESH_INTERVAL_SECONDS,
app_config_json: JSON.generate(config),
}
end
+19
View File
@@ -0,0 +1,19 @@
const CONFIG_SELECTOR = '[data-app-config]';
export function readAppConfig() {
const el = document.querySelector(CONFIG_SELECTOR);
if (!el) {
return {};
}
const raw = el.getAttribute('data-app-config') || '';
if (!raw) {
return {};
}
try {
const parsed = JSON.parse(raw);
return typeof parsed === 'object' && parsed !== null ? parsed : {};
} catch (err) {
console.error('Failed to parse application configuration', err);
return {};
}
}
+50
View File
@@ -0,0 +1,50 @@
import { readAppConfig } from './config.js';
import { initializeApp } from './main.js';
const DEFAULT_CONFIG = {
refreshMs: 60_000,
refreshIntervalSeconds: 60,
chatEnabled: true,
defaultChannel: '#MediumFast',
defaultFrequency: '868MHz',
mapCenter: { lat: 52.502889, lon: 13.404194 },
maxNodeDistanceKm: 137,
tileFilters: {
light: 'grayscale(1) saturate(0) brightness(0.92) contrast(1.05)',
dark: 'grayscale(1) invert(1) brightness(0.9) contrast(1.08)'
}
};
function mergeConfig(raw) {
const config = { ...DEFAULT_CONFIG, ...(raw || {}) };
config.mapCenter = {
lat: Number(raw?.mapCenter?.lat ?? DEFAULT_CONFIG.mapCenter.lat),
lon: Number(raw?.mapCenter?.lon ?? DEFAULT_CONFIG.mapCenter.lon)
};
config.tileFilters = {
light: raw?.tileFilters?.light || DEFAULT_CONFIG.tileFilters.light,
dark: raw?.tileFilters?.dark || DEFAULT_CONFIG.tileFilters.dark
};
const refreshIntervalSeconds = Number(
raw?.refreshIntervalSeconds ?? DEFAULT_CONFIG.refreshIntervalSeconds
);
config.refreshIntervalSeconds = Number.isFinite(refreshIntervalSeconds)
? refreshIntervalSeconds
: DEFAULT_CONFIG.refreshIntervalSeconds;
const refreshMs = Number(raw?.refreshMs ?? config.refreshIntervalSeconds * 1000);
config.refreshMs = Number.isFinite(refreshMs) ? refreshMs : DEFAULT_CONFIG.refreshMs;
config.chatEnabled = Boolean(raw?.chatEnabled ?? DEFAULT_CONFIG.chatEnabled);
config.defaultChannel = raw?.defaultChannel || DEFAULT_CONFIG.defaultChannel;
config.defaultFrequency = raw?.defaultFrequency || DEFAULT_CONFIG.defaultFrequency;
const maxDistance = Number(raw?.maxNodeDistanceKm ?? DEFAULT_CONFIG.maxNodeDistanceKm);
config.maxNodeDistanceKm = Number.isFinite(maxDistance)
? maxDistance
: DEFAULT_CONFIG.maxNodeDistanceKm;
return config;
}
document.addEventListener('DOMContentLoaded', () => {
const rawConfig = readAppConfig();
const config = mergeConfig(rawConfig);
initializeApp(config);
});
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
(function () {
'use strict';
function resolveBackgroundColor() {
if (!document.body) {
return null;
}
var color = '';
try {
var styles = window.getComputedStyle(document.body);
if (styles) {
color = styles.getPropertyValue('--bg');
if (color) {
color = color.trim();
}
}
} catch (err) {
color = '';
}
if (!color) {
color = document.body.classList.contains('dark') ? '#0e1418' : '#f6f3ee';
}
return color;
}
function applyBackground() {
var color = resolveBackgroundColor();
if (!color) {
return;
}
document.documentElement.style.backgroundColor = color;
document.documentElement.style.backgroundImage = 'none';
document.body.style.backgroundColor = color;
document.body.style.backgroundImage = 'none';
}
function init() {
applyBackground();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
window.addEventListener('themechange', applyBackground);
window.__potatoBackground = {
applyBackground: applyBackground,
resolveBackgroundColor: resolveBackgroundColor
};
})();
+58
View File
@@ -0,0 +1,58 @@
(function () {
var THEME_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
function getCookie(name) {
var matcher = new RegExp(
'(?:^|; )' + name.replace(/([.$?*|{}()\[\]\\/+^])/g, '\\$1') + '=([^;]*)'
);
var match = document.cookie.match(matcher);
return match ? decodeURIComponent(match[1]) : null;
}
function setCookie(name, value, opts) {
var options = Object.assign(
{ path: '/', 'max-age': THEME_COOKIE_MAX_AGE, SameSite: 'Lax' },
opts || {}
);
var updated = encodeURIComponent(name) + '=' + encodeURIComponent(value);
for (var k in options) {
if (!Object.prototype.hasOwnProperty.call(options, k)) continue;
updated += '; ' + k + (options[k] === true ? '' : '=' + options[k]);
}
document.cookie = updated;
}
function persistTheme(value) {
setCookie('theme', value, { 'max-age': THEME_COOKIE_MAX_AGE });
}
var theme = getCookie('theme');
if (theme !== 'dark' && theme !== 'light') {
theme = 'dark';
}
persistTheme(theme);
document.addEventListener('DOMContentLoaded', function () {
if (theme === 'dark') {
document.body.classList.add('dark');
} else {
document.body.classList.remove('dark');
}
var btn = document.getElementById('themeToggle');
if (btn) {
btn.textContent = document.body.classList.contains('dark') ? '☀️' : '🌙';
}
if (typeof window.applyFiltersToAllTiles === 'function') {
window.applyFiltersToAllTiles();
}
});
window.__themeCookie = {
getCookie: getCookie,
setCookie: setCookie,
persistTheme: persistTheme,
maxAge: THEME_COOKIE_MAX_AGE
};
})();
+931
View File
@@ -0,0 +1,931 @@
:root {
--bg: #f6f3ee;
--bg2: #ffffff;
--fg: #0c0f12;
--muted: #5c6773;
--card: rgba(0, 0, 0, 0.03);
--line: rgba(12, 15, 18, 0.08);
--accent: #2b6cb0;
--row-alt: rgba(0, 0, 0, 0.02);
--table-head-bg: rgba(0, 0, 0, 0.06);
--table-head-fg: var(--fg);
--pad: 16px;
--map-tile-filter-light: grayscale(1) saturate(0) brightness(0.92) contrast(1.05);
--map-tile-filter-dark: grayscale(1) invert(1) brightness(0.9) contrast(1.08);
}
body.dark {
--bg: #0e1418;
--bg2: #0e141b;
--fg: #e6ebf0;
--muted: #9aa7b4;
--card: rgba(255, 255, 255, 0.04);
--line: rgba(255, 255, 255, 0.1);
--accent: #5fa8ff;
--row-alt: rgba(255, 255, 255, 0.05);
--table-head-bg: rgba(255, 255, 255, 0.06);
--table-head-fg: var(--fg);
}
html,
body {
background-color: var(--bg);
color: var(--fg);
transition: background-color 160ms ease, color 160ms ease;
}
a {
color: var(--accent);
}
hr {
border-color: var(--line);
}
.card,
.panel,
.box {
background: var(--card);
backdrop-filter: blur(2px);
border: 1px solid var(--line);
border-radius: 10px;
}
table {
border-collapse: collapse;
width: 100%;
border: 1px solid var(--line);
}
thead th {
background: var(--table-head-bg);
color: var(--table-head-fg);
text-align: left;
border-bottom: 1px solid var(--line);
padding: 8px;
}
tbody td {
padding: 8px;
border-bottom: 1px solid var(--line);
}
tbody tr:nth-child(even) td {
background: var(--row-alt);
}
.leaflet-container {
background: transparent !important;
color: var(--fg);
}
.neighbor-connection-line {
cursor: pointer;
}
.neighbor-snr {
margin-left: 4px;
color: var(--muted);
font-size: 12px;
}
body {
font-family: system-ui, Segoe UI, Roboto, Ubuntu, Arial, sans-serif;
margin: var(--pad);
padding-bottom: 32px;
--map-tiles-filter: var(--map-tile-filter-light);
}
h1 {
margin: 0 0 8px;
}
.site-title {
display: inline-flex;
align-items: center;
gap: 12px;
}
.site-title img {
width: 52px;
height: 52px;
display: block;
border-radius: 12px;
}
.meta {
color: #555;
margin-bottom: 12px;
}
.pill {
display: inline-block;
padding: 2px 8px;
border-radius: 999px;
background: #eee;
font-size: 12px;
}
#map {
position: relative;
flex: 1;
height: 60vh;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
#map[data-map-status="placeholder"] {
background: repeating-linear-gradient(
135deg,
rgba(0, 0, 0, 0.02),
rgba(0, 0, 0, 0.02) 12px,
rgba(0, 0, 0, 0.04) 12px,
rgba(0, 0, 0, 0.04) 24px
);
}
#map .map-placeholder-message {
text-align: center;
color: #555;
font-size: 14px;
line-height: 1.5;
padding: 0 16px;
}
#map .map-placeholder-message strong {
display: block;
margin-bottom: 6px;
font-size: 16px;
}
#map .map-placeholder-message span {
display: block;
margin-top: 4px;
}
body.dark #map .map-placeholder-message {
color: #ddd;
}
#map .map-status-message {
position: absolute;
top: 12px;
left: 50%;
transform: translateX(-50%);
padding: 6px 12px;
border-radius: 999px;
font-size: 12px;
line-height: 1.2;
backdrop-filter: blur(6px);
pointer-events: none;
border: 1px solid rgba(0, 0, 0, 0.15);
background: rgba(255, 255, 255, 0.9);
color: #333;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
z-index: 1200;
}
body.dark #map[data-map-status="placeholder"] {
background: repeating-linear-gradient(
135deg,
rgba(255, 255, 255, 0.02),
rgba(255, 255, 255, 0.02) 12px,
rgba(255, 255, 255, 0.06) 12px,
rgba(255, 255, 255, 0.06) 24px
);
}
body.dark #map .map-status-message {
border-color: rgba(255, 255, 255, 0.16);
background: rgba(0, 0, 0, 0.65);
color: #eee;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}
table {
border-collapse: collapse;
width: 100%;
margin: 0;
}
th,
td {
padding: 4px 6px;
text-align: left;
}
th {
position: sticky;
top: 0;
background: #fafafa;
}
.mono {
font-family: ui-monospace, Menlo, Consolas, monospace;
}
.row {
display: flex;
gap: var(--pad);
align-items: center;
justify-content: space-between;
}
.map-row {
display: flex;
gap: var(--pad);
align-items: stretch;
}
#chat {
flex: 0 0 33%;
max-width: 33%;
height: 60vh;
border: 1px solid #ddd;
border-radius: 8px;
overflow-y: auto;
padding: 6px;
font-size: 12px;
}
.chat-entry-node {
font-family: ui-monospace, Menlo, Consolas, monospace;
color: #555;
}
.chat-entry-msg {
font-family: ui-monospace, Menlo, Consolas, monospace;
}
.chat-entry-date {
font-family: ui-monospace, Menlo, Consolas, monospace;
font-weight: bold;
}
.short-name {
display: inline-block;
border-radius: 4px;
padding: 0 2px;
}
.short-name[data-node-info] {
cursor: pointer;
}
.short-info-overlay {
position: absolute;
background: #fff;
color: #111;
border: 1px solid #ccc;
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
padding: 8px 10px 10px;
font-size: 11px;
line-height: 1.4;
min-width: 200px;
max-width: 240px;
z-index: 2000;
}
.short-info-overlay[hidden] {
display: none;
}
.short-info-overlay .short-info-close {
position: absolute;
top: 4px;
right: 4px;
border: none;
background: transparent;
font-size: 14px;
line-height: 1;
padding: 2px;
border-radius: 4px;
cursor: pointer;
color: inherit;
}
.short-info-overlay .short-info-close:hover {
background: rgba(0, 0, 0, 0.08);
}
.short-info-content {
margin: 0;
}
.meta-info {
display: flex;
flex-direction: column;
gap: 6px;
align-items: flex-start;
}
.refresh-row {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 12px;
align-items: start;
width: 100%;
}
.refresh-info {
margin: 0;
color: #555;
}
.refresh-actions {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
justify-self: end;
}
.auto-refresh-toggle {
display: inline-flex;
align-items: center;
gap: 6px;
}
.controls {
display: flex;
gap: 8px;
align-items: center;
}
.controls label {
display: inline-flex;
align-items: center;
gap: 6px;
}
.controls .filter-input {
display: inline-flex;
align-items: center;
flex: 1 1 260px;
position: relative;
}
.filter-input input[type="text"] {
flex: 1 1 auto;
width: 100%;
padding-right: 28px;
}
.filter-clear {
position: absolute;
right: 6px;
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
border: none;
background: transparent;
color: var(--muted);
font-size: 16px;
line-height: 1;
border-radius: 50%;
cursor: pointer;
padding: 0;
}
.filter-clear:hover {
background: rgba(0, 0, 0, 0.06);
}
body.dark .filter-clear:hover {
background: rgba(255, 255, 255, 0.12);
}
.filter-clear:focus-visible {
outline: 2px solid #4a90e2;
outline-offset: 2px;
}
button {
padding: 6px 10px;
border: 1px solid #ccc;
background: #fff;
border-radius: 6px;
cursor: pointer;
color: var(--fg);
}
button:hover {
background: #f6f6f6;
}
.sort-button {
padding: 0;
border: none;
background: none;
color: inherit;
font: inherit;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 4px;
}
.sort-button:hover {
background: none;
}
.sort-button:focus-visible {
outline: 2px solid #4a90e2;
outline-offset: 2px;
}
.sort-indicator {
font-size: 0.75em;
opacity: 0.6;
}
th[aria-sort] .sort-indicator {
opacity: 1;
}
label {
font-size: 14px;
color: #333;
}
input[type="text"] {
padding: 6px 10px;
border: 1px solid #ccc;
border-radius: 6px;
}
.legend {
position: relative;
background: #fff;
color: var(--fg);
padding: 8px 10px 10px;
border: 1px solid #ccc;
border-radius: 8px;
font-size: 12px;
line-height: 18px;
min-width: 160px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}
.legend-header {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 4px;
margin-bottom: 6px;
font-weight: 600;
}
.legend-title {
font-size: 13px;
}
.legend-items {
display: flex;
flex-direction: column;
gap: 2px;
}
.legend-item {
display: flex;
align-items: center;
gap: 6px;
font: inherit;
color: inherit;
background: transparent;
border: 1px solid transparent;
border-radius: 4px;
padding: 3px 6px;
cursor: pointer;
width: 100%;
justify-content: flex-start;
text-align: left;
}
.legend-item:hover {
background: rgba(0, 0, 0, 0.05);
}
.legend-item:focus-visible {
outline: 2px solid #4a90e2;
outline-offset: 2px;
}
.legend-item[aria-pressed="true"] {
border-color: rgba(0, 0, 0, 0.2);
background: rgba(0, 0, 0, 0.08);
}
.legend-swatch {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 2px;
}
.legend-hidden {
display: none !important;
}
.legend-toggle {
margin-top: 8px;
}
.legend-toggle-button {
font-size: 12px;
color: var(--fg);
}
#map .leaflet-tile-pane,
#map .leaflet-layer,
#map .leaflet-tile.map-tiles {
opacity: 0.75;
filter: var(--map-tiles-filter, var(--map-tile-filter-light));
-webkit-filter: var(--map-tiles-filter, var(--map-tile-filter-light));
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: #fff;
color: #333;
box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
}
#nodes {
font-size: 12px;
}
footer {
position: fixed;
bottom: 0;
left: var(--pad);
width: calc(100% - 2 * var(--pad));
background: #fafafa;
border-top: 1px solid #ddd;
text-align: center;
font-size: 12px;
padding: 4px 0;
}
.info-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
padding: var(--pad);
z-index: 4000;
}
.info-overlay[hidden] {
display: none;
}
.info-dialog {
background: #fff;
color: #111;
max-width: 420px;
width: min(100%, 420px);
border-radius: 12px;
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.2);
position: relative;
padding: 20px 24px;
outline: none;
}
.info-dialog:focus {
outline: 2px solid #4a90e2;
outline-offset: 4px;
}
.info-close {
position: absolute;
top: 10px;
right: 10px;
padding: 4px;
border: none;
background: transparent;
font-size: 20px;
line-height: 1;
border-radius: 999px;
}
.info-close:hover {
background: rgba(0, 0, 0, 0.06);
}
.info-title {
margin: 0 0 8px;
font-size: 20px;
}
.info-intro {
margin: 0 0 12px;
font-size: 14px;
color: #444;
}
.info-details {
margin: 0;
font-size: 14px;
line-height: 1.6;
}
.info-details dt {
font-weight: 600;
margin-top: 12px;
color: #222;
}
.info-details dd {
margin: 4px 0 0;
}
.info-details dd a {
color: inherit;
word-break: break-word;
}
@media (max-width: 1280px) {
#nodes th:nth-child(15),
#nodes td:nth-child(15),
#nodes th:nth-child(16),
#nodes td:nth-child(16),
#nodes th:nth-child(17),
#nodes td:nth-child(17),
#nodes th:nth-child(18),
#nodes td:nth-child(18) {
display: none;
}
}
@media (max-width: 1024px) {
.row {
flex-direction: column;
align-items: stretch;
gap: var(--pad);
}
.site-title img {
width: 44px;
height: 44px;
}
.map-row {
flex-direction: column;
}
.controls {
order: 2;
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto auto;
align-items: center;
width: 100%;
gap: 12px;
}
.controls .filter-input {
width: 100%;
}
.controls button {
justify-self: end;
}
.meta-info {
order: 1;
width: 100%;
}
.refresh-row {
grid-template-columns: 1fr;
row-gap: 8px;
}
.refresh-actions {
flex-direction: row;
align-items: center;
gap: 8px;
justify-self: start;
flex-wrap: nowrap;
}
#map {
order: 1;
flex: none;
max-width: 100%;
height: 50vh;
}
#chat {
order: 2;
flex: none;
max-width: 100%;
height: 30vh;
}
#nodes th:nth-child(1),
#nodes td:nth-child(1),
#nodes th:nth-child(5),
#nodes td:nth-child(5),
#nodes th:nth-child(6),
#nodes td:nth-child(6),
#nodes th:nth-child(9),
#nodes td:nth-child(9),
#nodes th:nth-child(11),
#nodes td:nth-child(11),
#nodes th:nth-child(13),
#nodes td:nth-child(13),
#nodes th:nth-child(14),
#nodes td:nth-child(14),
#nodes th:nth-child(15),
#nodes td:nth-child(15),
#nodes th:nth-child(16),
#nodes td:nth-child(16),
#nodes th:nth-child(17),
#nodes td:nth-child(17),
#nodes th:nth-child(18),
#nodes td:nth-child(18) {
display: none;
}
.legend {
max-width: min(240px, 80vw);
}
}
body.dark {
background: #111;
color: #eee;
--map-tiles-filter: var(--map-tile-filter-dark);
}
body.dark .meta {
color: #bbb;
}
body.dark .refresh-info {
color: #bbb;
}
body.dark .pill {
background: #444;
}
body.dark #map {
border-color: #444;
}
body.dark #chat {
border-color: #444;
background: #222;
color: #eee;
}
body.dark th {
background: #222;
}
body.dark button {
background: #333;
border-color: #444;
color: #eee;
}
body.dark button:hover {
background: #444;
}
body.dark .sort-button {
background: none;
border: none;
color: inherit;
}
body.dark .sort-button:hover {
background: none;
}
body.dark label {
color: #ddd;
}
body.dark input[type="text"] {
background: #222;
color: #eee;
border-color: #444;
}
body.dark .legend {
background: #333;
border-color: #444;
color: #eee;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
}
body.dark .legend-toggle-button {
background: #333;
border-color: #444;
color: #eee;
}
body.dark .legend-toggle-button:hover {
background: #444;
}
body.dark .legend-item:hover {
background: rgba(255, 255, 255, 0.1);
}
body.dark .legend-item[aria-pressed="true"] {
border-color: rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.16);
}
body.dark .leaflet-popup-content-wrapper,
body.dark .leaflet-popup-tip {
background: #333;
color: #eee;
box-shadow: 0 3px 14px rgba(0, 0, 0, 0.8);
}
body.dark footer {
background: #222;
border-top-color: #444;
color: #eee;
}
body.dark a {
color: #9bd;
}
body.dark .chat-entry-node {
color: #777;
}
body.dark .chat-entry-msg {
color: #bbb;
}
body.dark .short-name {
color: #555;
}
body.dark .chat-entry-date {
color: #bbb;
}
body.dark .info-overlay {
background: rgba(0, 0, 0, 0.7);
}
body.dark .info-dialog {
background: #1c1c1c;
color: #eee;
border: 1px solid #444;
}
body.dark .info-intro {
color: #bbb;
}
body.dark .info-details dt {
color: #ddd;
}
body.dark .info-close:hover {
background: rgba(255, 255, 255, 0.1);
}
body.dark .short-info-overlay {
background: #1c1c1c;
border-color: #444;
color: #eee;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
}
body.dark .short-info-overlay .short-info-close:hover {
background: rgba(255, 255, 255, 0.1);
}
#map .leaflet-tile-pane,
#map .leaflet-layer,
#map .leaflet-tile.map-tiles {
filter: var(--map-tiles-filter, var(--map-tile-filter-light));
-webkit-filter: var(--map-tiles-filter, var(--map-tile-filter-light));
}
body.dark #map .leaflet-tile-pane,
body.dark #map .leaflet-layer,
body.dark #map .leaflet-tile.map-tiles {
filter: var(--map-tiles-filter, var(--map-tile-filter-dark));
-webkit-filter: var(--map-tiles-filter, var(--map-tile-filter-dark));
}
+15 -3018
View File
File diff suppressed because it is too large Load Diff