From 29f1220400ea4138bee2fb282918b4239c88078f Mon Sep 17 00:00:00 2001 From: Aleksandr Meshchriakov Date: Fri, 20 Mar 2026 13:55:28 +0100 Subject: [PATCH] feat(admin): add dark azure-violet theme --- src/settings/base.py | 4 +- src/static/admin/css/mostovik-admin-theme.css | 487 ++++++++++++++++++ 2 files changed, 489 insertions(+), 2 deletions(-) create mode 100644 src/static/admin/css/mostovik-admin-theme.css diff --git a/src/settings/base.py b/src/settings/base.py index a2cf6c9..18af8a3 100644 --- a/src/settings/base.py +++ b/src/settings/base.py @@ -112,7 +112,7 @@ JAZZMIN_SETTINGS = { # Related modal "related_modal_active": True, # UI Tweaks - "custom_css": None, + "custom_css": "admin/css/mostovik-admin-theme.css", "custom_js": None, "use_google_fonts_cdn": True, "show_ui_builder": False, @@ -144,7 +144,7 @@ JAZZMIN_UI_TWEAKS = { "sidebar_nav_compact_style": False, "sidebar_nav_legacy_style": False, "sidebar_nav_flat_style": False, - "theme": "default", + "theme": "darkly", "dark_mode_theme": "darkly", "button_classes": { "primary": "btn-primary", diff --git a/src/static/admin/css/mostovik-admin-theme.css b/src/static/admin/css/mostovik-admin-theme.css new file mode 100644 index 0000000..d551156 --- /dev/null +++ b/src/static/admin/css/mostovik-admin-theme.css @@ -0,0 +1,487 @@ +@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@500&display=swap"); + +:root { + --mx-bg: #07101f; + --mx-bg-elevated: #0b1730; + --mx-bg-soft: #102245; + --mx-surface: rgba(13, 28, 58, 0.88); + --mx-surface-strong: rgba(16, 34, 69, 0.96); + --mx-border: rgba(91, 132, 255, 0.22); + --mx-border-strong: rgba(123, 93, 255, 0.42); + --mx-text: #e8f1ff; + --mx-text-muted: #9fb3d9; + --mx-text-dim: #7890bf; + --mx-azure: #39b8ff; + --mx-violet: #8e63ff; + --mx-violet-soft: #6d54f7; + --mx-success: #2dd4bf; + --mx-warning: #ffc857; + --mx-danger: #ff6b9f; + --mx-shadow: 0 24px 60px rgba(2, 6, 23, 0.45); +} + +html, +body, +.wrapper, +.content-wrapper, +.main-footer, +.login-page, +.register-page { + background: + radial-gradient(circle at top left, rgba(57, 184, 255, 0.16), transparent 28%), + radial-gradient(circle at top right, rgba(142, 99, 255, 0.18), transparent 24%), + linear-gradient(180deg, #050b16 0%, var(--mx-bg) 38%, #060d1a 100%); + color: var(--mx-text); + font-family: "IBM Plex Sans", "Segoe UI", sans-serif; +} + +body, +.content-wrapper, +.main-footer, +.content-header h1, +.content-header h1 small, +.content-wrapper .content, +.card-title, +.small-box, +.table, +.table th, +.table td, +.form-control, +.form-control:focus, +.select2-container--default .select2-selection--single, +.select2-container--default .select2-selection--multiple, +.select2-results__option, +.btn, +.nav-sidebar .nav-link, +.brand-text, +.login-box-msg, +.help, +.text-muted, +.small, +.errornote, +.messagelist li { + color: var(--mx-text); +} + +.main-header.navbar { + background: linear-gradient(90deg, rgba(8, 18, 38, 0.95), rgba(19, 35, 74, 0.95)); + border-bottom: 1px solid rgba(57, 184, 255, 0.18); + box-shadow: 0 10px 35px rgba(3, 7, 18, 0.28); + backdrop-filter: blur(14px); +} + +.main-header .nav-link, +.main-header .navbar-nav .nav-link { + color: var(--mx-text-muted); +} + +.main-header .nav-link:hover, +.main-header .navbar-nav .nav-link:hover { + color: var(--mx-text); +} + +.main-sidebar { + background: + linear-gradient(180deg, rgba(8, 18, 38, 0.98) 0%, rgba(9, 22, 48, 0.98) 100%), + radial-gradient(circle at top, rgba(142, 99, 255, 0.12), transparent 30%); + border-right: 1px solid rgba(142, 99, 255, 0.16); + box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.03); +} + +.brand-link { + border-bottom: 1px solid rgba(57, 184, 255, 0.18); + background: linear-gradient(90deg, rgba(11, 23, 48, 0.96), rgba(20, 33, 67, 0.96)); +} + +.brand-link .brand-text { + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.nav-sidebar > .nav-item > .nav-link { + margin: 0.18rem 0.55rem; + border-radius: 14px; + color: var(--mx-text-muted); + transition: background-color 0.18s ease, color 0.18s ease, transform 0.18s ease; +} + +.nav-sidebar > .nav-item > .nav-link:hover, +.nav-sidebar > .nav-item.menu-open > .nav-link, +.nav-sidebar .nav-treeview > .nav-item > .nav-link:hover { + background: rgba(57, 184, 255, 0.11); + color: var(--mx-text); + transform: translateX(2px); +} + +.nav-sidebar > .nav-item > .nav-link.active, +.nav-sidebar .nav-treeview > .nav-item > .nav-link.active { + background: linear-gradient(90deg, rgba(57, 184, 255, 0.18), rgba(142, 99, 255, 0.28)); + border: 1px solid rgba(142, 99, 255, 0.2); + color: #ffffff; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04); +} + +.nav-sidebar .nav-header { + color: var(--mx-text-dim); + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.content-wrapper { + background-color: transparent; +} + +.content-header h1 { + font-weight: 700; + letter-spacing: 0.01em; +} + +.content-header, +.main-footer, +.card, +.small-box, +.info-box, +.module, +div.breadcrumbs, +#changelist-filter, +.submit-row, +.inline-group, +.selector, +.selector-available h2, +.selector-chosen h2, +.login-card-body, +.card-body, +.card-header, +.login-logo, +.messagelist li, +.object-tools a, +.paginator, +.results, +fieldset.module, +.tabular.inline-related, +.tabular tr.form-row td, +.tabular tr.form-row th { + background: var(--mx-surface); + border: 1px solid var(--mx-border); + box-shadow: var(--mx-shadow); +} + +.content-header, +.main-footer, +.card, +.info-box, +.module, +.inline-group, +.selector, +.login-card-body, +fieldset.module { + border-radius: 20px; +} + +.card, +.module, +.inline-group, +fieldset.module, +.submit-row, +#changelist-filter, +.paginator { + backdrop-filter: blur(12px); +} + +.card-header, +.module h2, +.module caption, +.inline-group h2, +.selector-available h2, +.selector-chosen h2 { + background: linear-gradient(90deg, rgba(17, 40, 84, 0.94), rgba(33, 31, 90, 0.92)); + border-bottom: 1px solid rgba(57, 184, 255, 0.18); + color: #f6f9ff; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.card-header, +.module h2, +.module caption, +.inline-group h2 { + border-radius: 18px 18px 0 0; +} + +a, +.breadcrumb a, +div.breadcrumbs a, +.historylink, +.viewsitelink { + color: var(--mx-azure); +} + +a:hover, +.breadcrumb a:hover, +div.breadcrumbs a:hover { + color: #88d9ff; +} + +div.breadcrumbs, +.breadcrumb { + color: var(--mx-text-muted); +} + +table, +.results table, +#result_list, +.table { + background: transparent; + border-collapse: separate; + border-spacing: 0; +} + +.results thead th, +.table thead th { + background: rgba(18, 40, 84, 0.96); + border-bottom: 1px solid rgba(57, 184, 255, 0.14); + color: #dff2ff; + font-size: 0.76rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.results tbody tr, +.table tbody tr { + background: rgba(8, 19, 42, 0.62); +} + +.results tbody tr:nth-child(even), +.table tbody tr:nth-child(even) { + background: rgba(13, 26, 55, 0.74); +} + +.results tbody tr:hover, +.table tbody tr:hover { + background: rgba(30, 53, 104, 0.84); +} + +.results td, +.results th, +.table td, +.table th { + border-color: rgba(57, 184, 255, 0.08); + padding-top: 0.78rem; + padding-bottom: 0.78rem; + vertical-align: middle; +} + +input[type="text"], +input[type="password"], +input[type="email"], +input[type="number"], +input[type="url"], +input[type="search"], +input[type="date"], +input[type="file"], +select, +textarea, +.form-control, +.vTextField, +.vLargeTextField, +.vURLField, +.vIntegerField, +.select2-container--default .select2-selection--single, +.select2-container--default .select2-selection--multiple { + background: rgba(6, 16, 35, 0.9); + border: 1px solid rgba(57, 184, 255, 0.16); + border-radius: 14px; + color: var(--mx-text); + min-height: 2.7rem; +} + +textarea, +.vLargeTextField { + min-height: 8rem; +} + +input:focus, +select:focus, +textarea:focus, +.form-control:focus, +.select2-container--default.select2-container--focus .select2-selection--multiple, +.select2-container--default.select2-container--open .select2-selection--single { + background: rgba(10, 24, 49, 0.98); + border-color: rgba(142, 99, 255, 0.58); + box-shadow: 0 0 0 0.22rem rgba(142, 99, 255, 0.14); +} + +label, +.aligned label, +fieldset label, +.required label, +.form-row label { + color: #d8e7ff; + font-weight: 600; +} + +.help, +.helptext, +p.help, +.form-text, +small, +.text-muted { + color: var(--mx-text-dim) !important; +} + +.submit-row, +.object-tools, +.actions, +.paginator { + border-radius: 18px; +} + +.button, +input[type="submit"], +input[type="button"], +.submit-row input, +.object-tools a, +.btn, +a.button { + background: linear-gradient(135deg, rgba(57, 184, 255, 0.18), rgba(142, 99, 255, 0.36)); + border: 1px solid rgba(142, 99, 255, 0.34); + border-radius: 14px; + color: #f5fbff; + font-weight: 700; + letter-spacing: 0.02em; + text-shadow: none; + box-shadow: 0 12px 30px rgba(4, 10, 24, 0.25); +} + +.button.default, +input[type="submit"].default, +.btn-primary, +.object-tools a.addlink { + background: linear-gradient(135deg, rgba(41, 183, 255, 0.86), rgba(122, 95, 255, 0.88)); + border-color: rgba(139, 115, 255, 0.78); + color: #ffffff; +} + +.button:hover, +input[type="submit"]:hover, +input[type="button"]:hover, +.btn:hover, +a.button:hover, +.object-tools a:hover { + filter: brightness(1.08); + transform: translateY(-1px); +} + +.deletelink, +.btn-danger { + background: linear-gradient(135deg, rgba(255, 107, 159, 0.82), rgba(167, 53, 118, 0.88)); + border-color: rgba(255, 107, 159, 0.55); +} + +.messagelist li, +.errornote, +.success, +.warning { + border-radius: 16px; + padding: 0.95rem 1.1rem; +} + +.messagelist .success, +li.success { + border-left: 4px solid var(--mx-success); +} + +.messagelist .warning, +li.warning { + border-left: 4px solid var(--mx-warning); +} + +.messagelist .error, +.errornote, +li.error { + border-left: 4px solid var(--mx-danger); +} + +code, +pre, +tt, +.mono, +.readonly, +.file-upload, +.field-file_hash .readonly { + font-family: "JetBrains Mono", monospace; +} + +pre, +code { + background: rgba(7, 17, 35, 0.9); + border: 1px solid rgba(57, 184, 255, 0.14); + border-radius: 12px; + color: #c8f2ff; +} + +#changelist-filter h2, +#changelist-filter h3 { + color: #eff5ff; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +#changelist-filter li.selected a, +#changelist-filter a:hover { + color: #ffffff; +} + +.login-box .card, +.login-card-body { + border-radius: 24px; +} + +.login-logo a { + color: #f5fbff; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.login-page .card { + background: + linear-gradient(180deg, rgba(11, 23, 48, 0.96), rgba(16, 34, 69, 0.96)), + radial-gradient(circle at top, rgba(142, 99, 255, 0.14), transparent 26%); +} + +.pagination .page-link, +.paginator a, +.paginator .this-page { + background: rgba(7, 17, 35, 0.82); + border: 1px solid rgba(57, 184, 255, 0.14); + color: var(--mx-text); +} + +.pagination .active .page-link, +.paginator .this-page { + background: linear-gradient(135deg, rgba(57, 184, 255, 0.78), rgba(142, 99, 255, 0.8)); + border-color: rgba(142, 99, 255, 0.5); + color: #ffffff; +} + +::-webkit-scrollbar { + width: 12px; + height: 12px; +} + +::-webkit-scrollbar-track { + background: rgba(7, 16, 34, 0.9); +} + +::-webkit-scrollbar-thumb { + background: linear-gradient(180deg, rgba(57, 184, 255, 0.7), rgba(142, 99, 255, 0.74)); + border: 2px solid rgba(7, 16, 34, 0.9); + border-radius: 999px; +}