Files
OpenVPN-Monitoring-Simple/UI/artifacts/css/style.css
2026-01-09 21:07:45 +03:00

637 lines
13 KiB
CSS

/* --- THEME VARIABLES --- */
:root {
/* Light Theme */
--bg-body: #f6f8fa;
--bg-card: #ffffff;
--bg-element: #f6f8fa;
--bg-element-hover: #f1f3f5;
--bg-input: #ffffff;
--text-heading: #24292f;
--text-main: #57606a;
--text-muted: #8c959f;
--border-color: #d0d7de;
--border-subtle: #e9ecef;
--badge-border-active: #92bea5;
--badge-border-disconnected: #d47e80;
--accent-color: #0969da;
--success-bg: rgba(39, 174, 96, 0.15);
--success-text: #1a7f37;
--danger-bg: rgba(231, 76, 60, 0.15);
--danger-text: #cf222e;
--warning-bg: rgba(255, 193, 7, 0.15);
--warning-text: #9a6700;
--shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
--toggle-off-bg: #e9ecef;
--toggle-off-border: #d0d7de;
}
/* Dark Theme (Soft & Low Contrast) */
[data-theme="dark"] {
--bg-body: #0d1117;
--bg-card: #161b22;
--bg-element: #21262d;
/* Используем прозрачность для hover, чтобы текст не сливался */
--bg-element-hover: rgba(255, 255, 255, 0.03);
--bg-input: #0d1117;
--text-heading: #e6edf3;
/* Светлее для заголовков */
--text-main: #8b949e;
/* Мягкий серый для текста */
--text-muted: #6e7681;
/* ОЧЕНЬ мягкие границы (8% прозрачности белого) */
--border-color: rgba(240, 246, 252, 0.1);
--border-subtle: rgba(240, 246, 252, 0.05);
--badge-border-active: #3e6f40;
--badge-border-disconnected: #793837;
--accent-color: #58a6ff;
--success-bg: rgba(35, 134, 54, 0.15);
--success-text: #3fb950;
--danger-bg: rgba(218, 54, 51, 0.15);
--danger-text: #f85149;
--warning-bg: rgba(210, 153, 34, 0.15);
--warning-text: #d29922;
--shadow: none;
--toggle-off-bg: rgba(110, 118, 129, 0.1);
--toggle-off-border: rgba(240, 246, 252, 0.1);
}
body {
background-color: var(--bg-body);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
font-size: 0.9rem;
color: var(--text-main);
padding: 20px 0;
transition: background-color 0.3s ease, color 0.3s ease;
}
.container {
max-width: 95%;
margin: 0 auto;
}
@media (min-width: 1400px) {
.container {
max-width: 75%;
}
}
/* Layout Elements */
.header,
.card {
background-color: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: 6px;
box-shadow: var(--shadow);
margin-bottom: 20px;
transition: border-color 0.3s ease;
}
.header {
padding: 20px;
}
.border-bottom {
border-bottom: 1px solid var(--border-color) !important;
}
.card-header {
background: transparent;
border-bottom: 1px solid var(--border-color);
padding: 15px 20px;
font-weight: 600;
color: var(--text-heading);
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: var(--text-heading);
font-weight: 600;
}
.text-muted {
color: var(--text-muted) !important;
}
/* Blur Effect */
body.modal-open .main-content-wrapper {
filter: blur(8px) grayscale(20%);
transform: scale(0.99);
opacity: 0.6;
transition: all 0.4s ease;
pointer-events: none;
}
.main-content-wrapper {
transition: all 0.4s ease;
transform: scale(1);
filter: blur(0);
opacity: 1;
}
/* Buttons & Controls */
.btn-nav,
.btn-header,
.header-badge,
.header-timezone {
background: var(--bg-element);
border: 1px solid var(--border-color);
color: var(--text-heading);
transition: all 0.2s ease;
font-size: 0.85rem;
display: inline-flex;
align-items: center;
justify-content: center;
height: 36px;
/* Fixed height for consistency */
vertical-align: middle;
}
.btn-nav:hover,
.btn-header:hover {
background: var(--bg-element-hover);
border-color: var(--text-muted);
color: var(--text-heading);
}
.btn-nav.active {
background: var(--accent-color);
color: #ffffff;
border-color: var(--accent-color);
}
.btn-header {
padding: 0 12px;
border-radius: 6px;
min-width: 36px;
}
.btn-nav {
padding: 0 12px;
border-radius: 6px;
display: inline-flex;
align-items: center;
}
.header-badge,
.header-timezone {
padding: 0 12px;
border-radius: 6px;
display: inline-flex;
align-items: center;
}
/* Stats Cards & KPI */
.stats-info,
.kpi-grid {
display: flex;
gap: 15px;
flex-wrap: wrap;
margin-bottom: 15px;
}
.kpi-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 20px;
}
.stat-item {
background: var(--bg-card);
padding: 15px;
border-radius: 6px;
border: 1px solid var(--border-color);
flex: 1;
min-width: 180px;
box-shadow: var(--shadow);
}
.kpi-grid .stat-item {
padding: 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.stat-value {
font-size: 1.4rem;
font-weight: 600;
color: var(--text-heading);
line-height: 1.2;
}
.kpi-grid .stat-content h3 {
font-size: 1.6rem;
font-weight: 700;
color: var(--text-heading);
margin: 0;
line-height: 1.2;
}
.stat-label {
font-size: 0.85rem;
color: var(--text-muted);
margin-top: 5px;
}
/* Tables */
.table {
--bs-table-bg: transparent;
--bs-table-color: var(--text-main);
--bs-table-border-color: var(--border-color);
margin-bottom: 0;
}
.table th {
background-color: var(--bg-card);
color: var(--text-muted);
text-transform: uppercase;
font-size: 0.75rem;
letter-spacing: 0.5px;
border-bottom: 1px solid var(--border-color);
position: sticky;
top: 0;
z-index: 10;
cursor: pointer;
user-select: none;
padding: 12px 10px;
}
.table th:hover {
color: var(--text-heading);
}
.table th.active-sort {
color: var(--accent-color);
border-bottom-color: var(--accent-color);
}
.table td {
padding: 12px 10px;
border-bottom: 1px solid var(--border-subtle);
vertical-align: middle;
}
.table-hover tbody tr:hover {
background-color: var(--bg-element-hover);
}
.table-hover tbody tr:hover td,
.table-hover tbody tr:hover .font-monospace {
color: var(--text-heading);
}
.font-monospace {
color: var(--text-main);
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important;
}
/* Section Divider */
.section-divider td {
background-color: var(--bg-element) !important;
font-weight: 600;
color: var(--text-heading);
padding: 8px 15px;
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
font-size: 0.8rem;
}
/* Badges */
.status-badge {
padding: 4px 8px;
border-radius: 4px;
font-weight: 500;
font-size: 0.75rem;
border: 1px solid transparent;
}
.status-active,
.status-valid {
background-color: var(--success-bg);
color: var(--success-text);
border-color: var(--badge-border-active);
}
.status-disconnected,
.status-expired {
background-color: var(--danger-bg);
color: var(--danger-text);
border-color: var(--badge-border-disconnected);
}
.status-expiring {
background-color: var(--warning-bg);
color: var(--warning-text);
border: 1px solid transparent;
}
.badge-soft-warning {
background: var(--warning-bg);
color: var(--warning-text);
border: 1px solid transparent;
font-weight: 600;
font-size: 0.75rem;
padding: 5px 10px;
}
.client-link {
color: var(--text-heading);
text-decoration: none;
font-weight: 600;
cursor: pointer;
transition: color 0.2s;
}
.client-link:hover {
color: var(--accent-color);
}
.client-link i {
color: var(--text-muted);
transition: color 0.2s;
}
.client-link:hover i {
color: var(--accent-color);
}
/* Inputs */
.form-control,
.form-select,
.search-input {
background-color: var(--bg-input);
border: 1px solid var(--border-color);
color: var(--text-heading);
border-radius: 6px;
}
.form-control:focus,
.form-select:focus,
.search-input:focus {
background-color: var(--bg-input);
border-color: var(--accent-color);
color: var(--text-heading);
box-shadow: 0 0 0 2px rgba(9, 105, 218, 0.15);
outline: none;
}
.form-control::placeholder {
color: var(--text-muted);
opacity: 0.7;
}
.input-group-text {
background-color: var(--bg-element);
border: 1px solid var(--border-color);
color: var(--text-muted);
}
/* Toggle Switch */
.form-check-input {
background-color: var(--toggle-off-bg);
border-color: var(--toggle-off-border);
cursor: pointer;
}
.form-check-input:checked {
background-color: var(--accent-color);
border-color: var(--accent-color);
}
[data-theme="dark"] .form-check-input:not(:checked) {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%238b949e'/%3e%3c/svg%3e");
}
/* Sort Buttons */
.sort-btn-group {
display: flex;
}
.sort-btn {
background: var(--bg-input);
border: 1px solid var(--border-color);
padding: 6px 12px;
font-size: 0.85rem;
color: var(--text-main);
min-width: 100px;
text-align: center;
cursor: pointer;
transition: all 0.2s;
}
.sort-btn:first-child {
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
border-right: none;
}
.sort-btn:last-child {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.sort-btn:hover {
background-color: var(--bg-element-hover);
}
.sort-btn.active {
background-color: var(--bg-element-hover);
color: var(--text-heading);
border-color: var(--text-muted);
font-weight: 600;
z-index: 2;
}
/* Modals */
.modal-content {
background-color: var(--bg-card);
border: 1px solid var(--border-color);
color: var(--text-main);
box-shadow: 0 15px 50px rgba(0, 0, 0, 0.5);
}
.modal-header {
border-bottom: 1px solid var(--border-color);
}
.modal-footer {
border-top: 1px solid var(--border-color);
}
.btn-close {
filter: var(--btn-close-filter, none);
}
[data-theme="dark"] .btn-close {
filter: invert(1) grayscale(100%) brightness(200%);
}
.modal-backdrop.show {
opacity: 0.6;
background-color: #000;
}
.chart-controls {
background: var(--bg-element);
padding: 12px;
border-radius: 6px;
border: 1px solid var(--border-color);
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 10px;
}
.bg-white-custom {
background-color: var(--bg-input) !important;
border-color: var(--border-color) !important;
}
/* Charts & Dashboard Specifics */
.chart-container {
position: relative;
height: 320px;
width: 100%;
}
.modal-chart-container {
height: 400px;
width: 100%;
position: relative;
}
.pie-container {
position: relative;
height: 220px;
width: 100%;
display: flex;
justify-content: center;
}
.chart-header-controls {
display: flex;
align-items: center;
gap: 15px;
}
.legend-dot {
width: 10px;
height: 10px;
border-radius: 50%;
display: inline-block;
margin-right: 5px;
}
/* Certificates Specifics */
.category-header {
background: linear-gradient(135deg, var(--bg-element), var(--bg-element-hover));
border-left: 4px solid;
padding: 12px 20px;
margin: 0;
font-weight: 600;
}
.category-header.active {
border-left-color: var(--success-text);
color: var(--success-text);
}
.category-header.expired {
border-left-color: var(--danger-text);
color: var(--danger-text);
}
.certificate-file {
font-size: 0.8rem;
color: var(--text-muted);
margin-top: 2px;
}
.empty-state {
text-align: center;
padding: 40px 20px;
color: var(--text-muted);
}
.empty-state i {
font-size: 3rem;
margin-bottom: 15px;
opacity: 0.5;
}
.cert-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid var(--border-subtle);
}
.cert-item:last-child {
border-bottom: none;
}
/* Utilities */
.refresh-indicator {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* Responsive */
@media (max-width: 768px) {
.header-controls {
flex-wrap: wrap;
gap: 8px;
}
.stats-info {
flex-direction: column;
}
.chart-controls {
flex-direction: column;
align-items: flex-start;
}
.chart-controls>div {
width: 100%;
}
.kpi-grid {
grid-template-columns: 1fr;
}
.chart-header-controls {
flex-wrap: wrap;
margin-top: 10px;
}
}