Russian-ALPR / static /style.css
Naumeex's picture
Initial deploy: Russian ALPR
186b436
Raw
History Blame Contribute Delete
22.4 kB
:root {
--bg: #f5f6f8;
--surface: #ffffff;
--surface-2: #f9f9f9;
--surface-3: #f5f5f5;
--text: #1a1a1a;
--text-muted: #555555;
--text-faint: #888888;
--border: #dddddd;
--border-light: #eeeeee;
--topbar-bg: #1a1a1a;
--topbar-text: #ffffff;
--topbar-text-muted: #cccccc;
--accent: #4caf50;
--accent-hover: #43a047;
--accent-bg: #f0f9f1;
--shadow: rgba(0,0,0,0.05);
--shadow-hover: rgba(0,0,0,0.08);
--code-bg: #f0f0f0;
--danger: #e53935;
--danger-hover: #c62828;
}
[data-theme="dark"] {
--bg: #15171c;
--surface: #1e2128;
--surface-2: #252932;
--surface-3: #2a2f3a;
--text: #e8eaed;
--text-muted: #9aa0a6;
--text-faint: #80868b;
--border: #3c4043;
--border-light: #2a2e35;
--topbar-bg: #0d0f13;
--topbar-text: #ffffff;;
--topbar-text-muted: #ffffff;;
--accent: #66bb6a;
--accent-hover: #81c784;
--accent-bg: #1b2e1d;
--shadow: rgba(0,0,0,0.3);
--shadow-hover: rgba(0,0,0,0.5);
--code-bg: #2a2f3a;
--danger: #ef5350;
--danger-hover: #e53935;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
transition: background 0.25s, color 0.25s;
}
.container {
max-width: 1100px;
margin: 0 auto;
padding: 0 20px;
}
.topbar {
background: var(--topbar-bg);
color: var(--topbar-text);
padding: 14px 0;
margin-bottom: 30px;
transition: background 0.25s;
}
.topbar .container { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; }
.logo {
display: inline-flex;
align-items: center;
color: var(--topbar-text);
text-decoration: none;
transition: opacity 0.15s;
}
.logo:hover { opacity: 0.85; }
.logo img { display: block; }
.topbar nav { display: flex; align-items: center; }
.topbar nav a {
color: var(--topbar-text-muted);
text-decoration: none;
margin-left: 20px;
padding: 6px 0;
border-bottom: 2px solid transparent;
transition: all 0.2s;
}
.topbar nav a:hover, .topbar nav a.active { color: var(--topbar-text); border-bottom-color: var(--accent); }
main { min-height: 60vh; }
footer {
margin-top: 60px;
padding: 30px 20px;
text-align: center;
color: var(--text-faint);
font-size: 0.9rem;
}
h1 { margin-bottom: 12px; font-size: 1.8rem; }
h2 { margin: 24px 0 12px; font-size: 1.4rem; }
h3 { margin-bottom: 10px; font-size: 1rem; color: var(--text-muted); }
.lead { color: var(--text-muted); margin-bottom: 24px; font-size: 1.05rem; }
/* --- Dropzone --- */
.dropzone {
display: block;
border: 2.5px dashed #aaa;
border-radius: 12px;
padding: 50px 20px;
text-align: center;
cursor: pointer;
background: var(--surface);
transition: all 0.2s;
margin-bottom: 16px;
}
.dropzone:hover, .dropzone.dragover { border-color: var(--accent); background: var(--accent-bg); }
.dropzone.has-file { border-color: var(--accent); border-style: solid; }
.dz-text { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.dz-icon { font-size: 2.5rem; }
.dz-text strong { font-size: 1.1rem; }
.dz-hint, .dz-formats { color: var(--text-faint); font-size: 0.9rem; }
/* --- Кнопки --- */
button, .btn-secondary, .btn-link, .btn-back, .btn-danger {
display: inline-block;
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 1rem;
cursor: pointer;
text-decoration: none;
transition: all 0.2s;
}
#submitBtn, .search-form button { background: var(--accent); color: var(--surface); width: 100%; font-weight: 600; }
#submitBtn:hover:not(:disabled), .search-form button:hover { background: var(--accent-hover); }
#submitBtn:disabled { background: var(--border); cursor: not-allowed; }
.btn-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); margin-top: 16px; }
.btn-secondary:hover { background: var(--code-bg); }
.btn-back { color: var(--text-muted); padding: 6px 0; }
.btn-back:hover { color: var(--text); }
.btn-danger { background: #e53935; color: var(--surface); margin-top: 16px; }
.btn-danger:hover { background: #c62828; }
.btn-link { color: var(--accent); padding: 0; font-size: 0.9rem; }
/* --- Статусы --- */
.status {
margin: 20px 0;
padding: 14px 18px;
border-radius: 6px;
font-size: 0.95rem;
}
.status-loading { background: var(--surface)3cd; color: #856404; }
.status-error { background: #f8d7da; color: #721c24; }
/* --- Результат --- */
.result {
margin-top: 30px;
background: var(--surface);
padding: 24px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.result img { max-width: 100%; border-radius: 8px; margin: 12px 0 20px; }
/* --- Карточки детекций --- */
.plate-card {
padding: 16px;
border-radius: 8px;
background: var(--surface-2);
border-left: 4px solid var(--border);
margin-bottom: 12px;
}
.plate-card.valid { border-left-color: var(--accent); }
.plate-card.invalid { border-left-color: #ff9800; }
.plate-text {
font-family: "JetBrains Mono", "Courier New", monospace;
font-size: 1.6rem;
font-weight: 700;
margin-bottom: 8px;
letter-spacing: 1px;
}
.plate-meta { display: flex; flex-wrap: wrap; gap: 16px; color: var(--text-muted); font-size: 0.9rem; margin-bottom: 8px; }
.plate-meta code { background: var(--surface); padding: 1px 6px; border-radius: 3px; }
/* --- Поиск --- */
.search-form {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.search-form input {
flex: 1;
padding: 12px 16px;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 1rem;
}
.search-form input:focus { outline: none; border-color: var(--accent); }
.search-form button { width: auto; padding: 12px 28px; }
.search-meta { color: var(--text-muted); margin-bottom: 20px; }
/* --- Сетка результатов --- */
.plates-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 16px;
}
.plate-tile {
background: var(--surface);
border-radius: 10px;
overflow: hidden;
text-decoration: none;
color: inherit;
transition: transform 0.15s, box-shadow 0.15s;
border-left: 4px solid var(--border);
}
/* --- Access banner на главной --- */
.access-banner {
padding: 12px 16px;
border-radius: 6px;
font-weight: 700;
font-size: 1.05rem;
margin-bottom: 12px;
text-align: center;
}
.access-allowed { background: #d4edda; color: #155724; }
.access-denied { background: #f8d7da; color: #721c24; }
.access-unknown { background: var(--surface)3cd; color: #856404; }
.emp-info {
background: var(--surface);
padding: 12px 14px;
border-radius: 6px;
margin-bottom: 10px;
border: 1px solid var(--border);
}
.emp-meta { color: var(--text-muted); font-size: 0.9rem; margin-top: 2px; }
.emp-note { color: #b71c1c; font-size: 0.9rem; margin-top: 6px; }
/* --- Registry --- */
.registry-header {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 20px;
}
.btn-primary {
background: var(--accent);
color: var(--surface);
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.95rem;
font-weight: 600;
}
.btn-primary:hover { background: var(--accent-hover); }
.registry-filters {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 20px;
background: var(--surface);
padding: 16px;
border-radius: 8px;
}
.registry-filters input,
.registry-filters select {
padding: 10px 12px;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 0.95rem;
}
.registry-filters input { flex: 1; min-width: 200px; }
.registry-filters button {
padding: 10px 20px;
background: var(--topbar-bg);
color: var(--surface);
border: none;
border-radius: 6px;
cursor: pointer;
width: auto;
}
.registry-table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.registry-table thead { background: var(--surface-3); }
.registry-table th {
padding: 12px;
text-align: left;
color: var(--text-muted);
font-weight: 600;
font-size: 0.9rem;
border-bottom: 2px solid var(--border);
}
.registry-table td {
padding: 12px;
border-bottom: 1px solid var(--border-light);
font-size: 0.95rem;
}
.registry-table tr:hover { background: #fafafa; }
.emp-name { font-weight: 600; }
.plate-code {
font-family: "JetBrains Mono", "Courier New", monospace;
background: var(--code-bg);
padding: 3px 8px;
border-radius: 4px;
font-weight: 600;
letter-spacing: 0.5px;
}
.emp-notes { color: var(--text-faint); font-size: 0.85rem; max-width: 200px; }
/* Toggle switch */
.toggle { display: inline-block; width: 40px; height: 22px; position: relative; vertical-align: middle; margin-right: 8px; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
background: var(--border);
border-radius: 22px;
cursor: pointer;
transition: 0.3s;
}
.toggle-slider:before {
content: "";
position: absolute;
height: 16px; width: 16px;
left: 3px; bottom: 3px;
background: white;
border-radius: 50%;
transition: 0.3s;
}
.toggle input:checked + .toggle-slider { background: var(--accent); }
.toggle input:checked + .toggle-slider:before { transform: translateX(18px); }
.access-badge {
font-size: 0.85rem;
padding: 3px 8px;
border-radius: 4px;
display: inline-block;
vertical-align: middle;
}
.access-badge.allowed { background: #d4edda; color: #155724; }
.access-badge.denied { background: #f8d7da; color: #721c24; }
.btn-small {
width: 32px;
height: 32px;
padding: 0;
margin-right: 4px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
line-height: 1;
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: middle;
}
.btn-edit { background: #e3f2fd; color: #1976d2; }
.btn-edit:hover { background: #bbdefb; }
.btn-del { background: #ffebee; color: #c62828; }
.btn-del:hover { background: #ffcdd2; }
/* Modal */
.modal {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
padding: 20px;
}
.modal-content {
background: white;
border-radius: 10px;
padding: 30px;
width: 100%;
max-width: 500px;
max-height: 90vh;
overflow-y: auto;
}
.modal-content h2 { margin-bottom: 20px; }
.modal-content label {
display: block;
margin-bottom: 14px;
font-size: 0.9rem;
color: var(--text-muted);
}
.modal-content label small { color: var(--text-faint); font-weight: normal; }
.modal-content input[type="text"],
.modal-content textarea {
width: 100%;
padding: 9px 12px;
border: 1px solid var(--border);
border-radius: 5px;
font-size: 0.95rem;
margin-top: 4px;
font-family: inherit;
}
.modal-content input:focus,
.modal-content textarea:focus { outline: none; border-color: var(--accent); }
.checkbox-label {
display: flex !important;
align-items: center;
gap: 8px;
}
.checkbox-label input { width: auto !important; margin: 0 !important; }
.modal-actions {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
}
.modal-actions button { width: auto; padding: 10px 20px; }
.plate-tile:hover { transform: translateY(-2px); box-shadow: 0 4px 14px rgba(0,0,0,0.08); }
.plate-tile.valid { border-left-color: var(--accent); }
.plate-tile.invalid { border-left-color: #ff9800; }
.plate-tile img { width: 100%; height: 160px; object-fit: cover; display: block; }
.tile-body { padding: 12px 14px; }
.tile-plate {
font-family: "JetBrains Mono", "Courier New", monospace;
font-weight: 700;
font-size: 1.15rem;
letter-spacing: 0.5px;
}
.tile-meta { display: flex; justify-content: space-between; color: var(--text-faint); font-size: 0.85rem; margin-top: 4px; }
.no-results { color: var(--text-faint); text-align: center; padding: 40px 20px; }
.no-results a { color: var(--accent); }
/* --- Детальная страница --- */
.detail { display: grid; gap: 30px; margin-top: 20px; }
@media (min-width: 800px) {
.detail { grid-template-columns: 2fr 1fr; }
}
.detail-images { display: flex; flex-direction: column; gap: 20px; }
.detail-images img { width: 100%; border-radius: 8px; }
.detail-info { background: var(--surface); padding: 24px; border-radius: 10px; }
.big-plate {
font-family: "JetBrains Mono", "Courier New", monospace;
color: var(--accent);
letter-spacing: 1px;
}
.meta-table { width: 100%; margin-top: 16px; border-collapse: collapse; }
.meta-table th, .meta-table td { padding: 10px 0; text-align: left; border-bottom: 1px solid var(--border-light); font-size: 0.95rem; }
.meta-table th { color: var(--text-faint); font-weight: 500; width: 45%; }
.meta-table code { background: var(--surface-3); padding: 2px 6px; border-radius: 3px; }
.modal[hidden] {
display: none !important;
}
/* --- Пагинация --- */
.pagination {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
margin: 30px 0;
flex-wrap: wrap;
}
.page-link {
display: inline-block;
padding: 8px 14px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
color: var(--text);
text-decoration: none;
font-size: 0.95rem;
transition: all 0.15s;
min-width: 40px;
text-align: center;
}
.page-link:hover:not(.disabled):not(.active) {
background: var(--accent-bg);
border-color: var(--accent);
color: var(--accent);
}
.page-link.active {
background: var(--accent);
color: var(--surface);
border-color: var(--accent);
font-weight: 600;
}
.page-link.disabled {
color: var(--border);
cursor: not-allowed;
}
.page-ellipsis {
padding: 8px 4px;
color: var(--text-faint);
}
.page-info {
color: var(--text-faint);
font-size: 0.9rem;
margin-left: 12px;
}
@media (max-width: 600px) {
.page-info { width: 100%; text-align: center; margin: 8px 0 0; }
}
/* --- Быстрая проверка на главной --- */
.quick-check {
margin-top: 40px;
background: var(--surface);
padding: 24px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.lead-small {
color: var(--text-muted);
margin-bottom: 16px;
font-size: 0.95rem;
}
.quick-tabs {
display: flex;
gap: 4px;
margin-bottom: 12px;
background: var(--surface-3);
padding: 4px;
border-radius: 8px;
}
.qtab {
flex: 1;
padding: 8px 12px;
background: transparent;
border: none;
border-radius: 6px;
cursor: pointer;
color: var(--text-muted);
font-size: 0.95rem;
transition: all 0.15s;
}
.qtab:hover { background: rgba(255,255,255,0.5); color: var(--text); }
.qtab.active {
background: var(--surface);
color: var(--text);
font-weight: 600;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.quick-form {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
.quick-form input {
flex: 1;
padding: 11px 14px;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 1rem;
}
.quick-form input:focus { outline: none; border-color: var(--accent); }
.quick-form button {
padding: 11px 22px;
background: var(--topbar-bg);
color: var(--surface);
border: none;
border-radius: 6px;
cursor: pointer;
width: auto;
font-weight: 500;
}
.quick-form button:hover { background: #000; }
.quick-loading {
color: var(--text-faint);
padding: 16px;
text-align: center;
}
.quick-match {
margin-bottom: 14px;
}
/* --- Переключатель темы --- */
/* --- Переключатель темы (toggle-switch) --- */
.theme-switch {
display: inline-block;
position: relative;
width: 52px;
height: 26px;
margin-left: 20px;
cursor: pointer;
vertical-align: middle;
}
.theme-switch input {
opacity: 0;
width: 0;
height: 0;
}
.theme-slider {
position: absolute;
inset: 0;
background: #3a3a3a;
border: 1px solid var(--topbar-text-muted);
border-radius: 26px;
transition: background 0.25s;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 5px;
box-sizing: border-box;
}
/* Иконки внутри */
.theme-icon {
font-size: 12px;
line-height: 1;
z-index: 1;
opacity: 0.6;
}
.theme-icon.sun { color: #ffd54f; }
.theme-icon.moon { color: #bbb; }
/* Бегунок */
.theme-slider::before {
content: "";
position: absolute;
height: 20px;
width: 20px;
left: 2px;
top: 50%;
transform: translateY(-50%);
background: #fff;
border-radius: 50%;
transition: transform 0.25s;
z-index: 2;
}
/* В тёмной теме (checkbox checked) бегунок вправо */
.theme-switch input:checked + .theme-slider::before {
transform: translate(26px, -50%);
}
.theme-switch input:checked + .theme-slider {
background: #1a3a5c;
}
/* ============================================
ИСПРАВЛЕНИЯ ТЁМНОЙ/СВЕТЛОЙ ТЕМЫ
(перекрывает проблемные места)
============================================ */
/* --- Кнопки: основной зелёный текст всегда белый --- */
#submitBtn,
.search-form button,
.btn-primary,
.registry-filters button,
.quick-form button {
color: #ffffff;
}
/* Чёрная кнопка (поиск/проверка) — в тёмной теме делаем светлее */
.registry-filters button,
.quick-form button {
background: var(--text);
color: var(--bg);
}
.registry-filters button:hover,
.quick-form button:hover {
opacity: 0.85;
}
/* --- Вторичная кнопка (Отмена) --- */
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover { background: var(--surface-3); }
/* --- Модалка: фон и текст по теме --- */
.modal-content {
background: var(--surface);
color: var(--text);
}
.modal-content h2 { color: var(--text); }
.modal-content label { color: var(--text-muted); }
.modal-content input[type="text"],
.modal-content textarea {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
/* --- Hover в реестре: мягкий, не ослепительный --- */
.registry-table tr:hover {
background: var(--surface-2);
}
/* --- Таблица реестра: фон и бордеры по теме --- */
.registry-table { background: var(--surface); }
.registry-table thead { background: var(--surface-3); }
.registry-table th {
color: var(--text-muted);
border-bottom: 2px solid var(--border);
}
.registry-table td {
color: var(--text);
border-bottom: 1px solid var(--border-light);
}
/* --- Карточки и поверхности --- */
.result,
.quick-check,
.plate-tile,
.detail-info,
.emp-info,
.registry-filters {
background: var(--surface);
color: var(--text);
}
.plate-card { background: var(--surface-2); }
/* --- Dropzone --- */
.dropzone {
background: var(--surface);
border-color: var(--border);
}
.dropzone:hover, .dropzone.dragover {
background: var(--accent-bg);
border-color: var(--accent);
}
/* --- Код-плашки --- */
code, .plate-code, .plate-meta code, .meta-table code {
background: var(--code-bg);
color: var(--text);
}
/* --- Поля поиска и фильтров --- */
.search-form input,
.registry-filters input,
.registry-filters select,
.quick-form input {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
/* --- Вкладки быстрой проверки --- */
.quick-tabs { background: var(--surface-3); }
.qtab { color: var(--text-muted); }
.qtab.active {
background: var(--surface);
color: var(--text);
}
/* --- Пагинация --- */
.page-link {
background: var(--surface);
border: 1px solid var(--border);
color: var(--text);
}
.page-link:hover:not(.disabled):not(.active) {
background: var(--accent-bg);
border-color: var(--accent);
color: var(--accent);
}
/* --- Метатаблица на детальной --- */
.meta-table th { color: var(--text-faint); }
.meta-table th, .meta-table td { border-bottom: 1px solid var(--border-light); }
/* --- Заголовок таблицы статусов доступа (зелёный/красный badge) ---
оставляем как есть — они читаются в обеих темах */
/* Фикс: навигация в шапке всегда светлая */
.topbar nav a {
color: var(--topbar-text-muted) !important;
}
.topbar nav a:hover,
.topbar nav a.active {
color: var(--topbar-text) !important;
}
/* Кнопка распознавания: явные цвета по состояниям */
#submitBtn {
background: var(--accent);
color: #ffffff;
}
#submitBtn:disabled {
background: #cccccc;
color: #888888;
}
/* Фикс: toggle доступа в реестре виден в обеих темах */
.toggle-slider {
background: #cccccc;
}
.toggle input:checked + .toggle-slider {
background: var(--accent);
}
.source-badge {
display: inline-block;
font-size: 0.75rem;
background: var(--accent-bg);
color: var(--accent);
padding: 3px 10px;
border-radius: 12px;
vertical-align: middle;
margin-left: 8px;
font-weight: 600;
}
/* --- Видео в детальной карточке --- */
.detail-video {
width: 100%;
border-radius: 8px;
background: #000;
display: block;
}
.video-hint {
margin-top: 8px;
color: var(--text-faint);
font-size: 0.85rem;
}
.video-tag {
font-size: 0.8rem;
margin-left: 4px;
}