Files
RoleForge/app/static/css/styles.css
Sergey Antropoff 9727ff6402 Molecule и Docker-тесты: vendored create playbook и явная платформа образа
- Добавлен molecule docker create playbook (create.yml + tasks/create_network.yml)
  с правкой tmpfs: словарь из molecule-plugins приводится к списку строк для
  community.docker.docker_container; сценарии копируют playbook и задают
  provisioner.playbooks.create.
- Для systemd-платформ tmpfs задаётся списком строк вместо mounts.
- В опциях ОС — run_platform (каноническая архитектура после build); в
  TestHostSpec и hosts теста передаётся platform в molecule/docker_container,
  чтобы на ARM не падал /sbin/init из-за amd64 без --platform.
- Страницы роли (просмотр и создание): одна dashboard-карточка на всю ширину,
  вкладки Role details / Role file catalog в
2026-05-05 08:56:54 +03:00

5325 lines
131 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* K3s Dashboard — design inspired by AppsTemplate layout, orange accent system */
:root {
--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-mono: "JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace;
/* Orange scale (primary UI) */
--orange-50: #fff7ed;
--orange-100: #ffedd5;
--orange-200: #fed7aa;
--orange-300: #fdba74;
--orange-400: #fb923c;
--orange-500: #f97316;
--orange-600: #ea580c;
--orange-700: #c2410c;
--orange-glow: rgba(249, 115, 22, 0.45);
--bg: #0d1017;
--bg-elevated: #12161f;
--bg-panel: #161b26;
--card: #1a1f2c;
--card-border: #2a3142;
--border: #2d3548;
--text: #e8ecf4;
--muted: #8b95a8;
--input: #141922;
--input-border: #3d4558;
--hover: rgba(255, 255, 255, 0.06);
--accent: var(--orange-500);
--accent-soft: rgba(249, 115, 22, 0.14);
--accent-border: rgba(251, 146, 60, 0.45);
--sidebar-width: 272px;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--shadow-card: 0 4px 24px rgba(0, 0, 0, 0.35);
--shadow-sidebar: 4px 0 32px rgba(0, 0, 0, 0.25);
/* Forms (AppsTemplate-style, orange focus) */
--form-transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
--form-focus-ring: 0 0 0 0.2rem rgba(249, 115, 22, 0.28);
--form-check-bg: var(--input);
--form-switch-track-off: #475569;
}
body[data-theme="light"] {
--bg: #f4f2ef;
--bg-elevated: #ffffff;
--bg-panel: #ffffff;
--card: #ffffff;
--card-border: #e8e4df;
--border: #e2ddd6;
/* основной текст — тёмно-серый, не «чёрный»; панель подменю в .sidebar фиксирована отдельно */
--text: #3a4048;
--muted: #5e6670;
--input: #ffffff;
--input-border: #d4cec6;
--hover: rgba(249, 115, 22, 0.08);
--accent-soft: rgba(249, 115, 22, 0.12);
--accent-border: rgba(234, 88, 12, 0.35);
--shadow-card: 0 2px 16px rgba(26, 29, 36, 0.08);
--shadow-sidebar: 2px 0 20px rgba(26, 29, 36, 0.06);
--form-switch-track-off: #d1d5db;
--form-check-bg: #ffffff;
/* светлая плашка внутри форм/pre/code без «тёмного» smudge */
--form-surface-elevated: #f8f6f3;
--form-surface-elevated-border: #e8e4df;
color-scheme: light;
}
* { box-sizing: border-box; }
/* color-scheme: нативные input/select/textarea (см. initTheme: data-theme дублируется на html) */
html {
scroll-behavior: smooth;
color-scheme: dark;
}
html[data-theme="light"] {
color-scheme: light;
}
body {
margin: 0;
font-family: var(--font-sans);
background: var(--bg);
color: var(--text);
line-height: 1.55;
min-height: 100vh;
transition: background 0.25s ease, color 0.25s ease;
}
body[data-theme="dark"] {
background:
radial-gradient(ellipse 120% 80% at 100% -20%, rgba(249, 115, 22, 0.12), transparent 50%),
radial-gradient(ellipse 80% 50% at 0% 100%, rgba(234, 88, 12, 0.06), transparent 45%),
var(--bg);
}
body[data-theme="light"] {
background:
radial-gradient(ellipse 100% 60% at 100% 0%, rgba(251, 146, 60, 0.15), transparent 55%),
var(--bg);
}
/* —— Page transition: центр, спиннер, размытие контента под оверлеем —— */
html.page-loading {
overflow: hidden;
cursor: wait;
}
html.page-loading .app-page-loader {
pointer-events: auto;
opacity: 1;
visibility: visible;
transition: opacity 0.15s ease;
}
.app-page-loader {
position: fixed;
inset: 0;
z-index: 300;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
opacity: 0;
visibility: hidden;
-webkit-backdrop-filter: blur(10px) saturate(1.05);
backdrop-filter: blur(10px) saturate(1.05);
background: color-mix(in srgb, var(--bg) 50%, rgba(0, 0, 0, 0.18));
transition: opacity 0.2s ease, visibility 0.2s;
}
body[data-theme="light"] .app-page-loader {
background: color-mix(in srgb, var(--bg) 45%, rgba(255, 255, 255, 0.55));
-webkit-backdrop-filter: blur(12px) saturate(1.1);
backdrop-filter: blur(12px) saturate(1.1);
}
.app-page-loader__spinner {
width: 46px;
height: 46px;
border-radius: 50%;
box-sizing: border-box;
border: 3px solid color-mix(in srgb, var(--orange-500) 22%, transparent);
border-top-color: var(--orange-500);
animation: app-page-loader-spin 0.7s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.app-page-loader { transition: none; }
html.page-loading .app-page-loader { transition: none; }
.app-page-loader__spinner { animation: none; border-color: var(--orange-500); }
}
@keyframes app-page-loader-spin {
to { transform: rotate(360deg); }
}
/* —— App shell (AppsTemplate-like: fixed sidebar + main) —— */
.layout {
display: grid;
grid-template-columns: var(--sidebar-width) 1fr;
min-height: 100vh;
animation: fade-in 0.35s ease;
}
.sidebar {
position: relative;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #1e2433 0%, #12161f 55%, #0d1017 100%);
border-right: 1px solid var(--border);
box-shadow: var(--shadow-sidebar);
z-index: 40;
}
.sidebar::before {
content: "";
position: absolute;
inset: 0 auto 0 0;
width: 3px;
background: linear-gradient(180deg, var(--orange-400), var(--orange-600));
opacity: 0.85;
pointer-events: none;
}
.sidebar-inner {
--sidebar-inner-pad-x: 14px;
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
padding: 0 var(--sidebar-inner-pad-x) 16px;
}
/* Оранжевый wash на всю ширину .sidebar, а не только колонку с padding у inner */
.sidebar-header {
margin-left: calc(-1 * var(--sidebar-inner-pad-x));
margin-right: calc(-1 * var(--sidebar-inner-pad-x));
padding: 22px calc(var(--sidebar-inner-pad-x) + 6px) 18px;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
margin-bottom: 8px;
background: linear-gradient(180deg, rgba(249, 115, 22, 0.14) 0%, rgba(249, 115, 22, 0.04) 45%, transparent 100%);
}
.brand {
display: flex;
align-items: center;
gap: 12px;
margin: 0;
line-height: 1.2;
}
.brand-text {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.brand-name {
font-size: 1.05rem;
font-weight: 800;
letter-spacing: -0.02em;
color: #fff;
line-height: 1.15;
}
.brand-tagline {
display: block;
font-size: 0.72rem;
font-weight: 600;
color: var(--muted);
letter-spacing: 0.04em;
margin-top: 3px;
line-height: 1.25;
}
body[data-theme="light"] .sidebar .brand-tagline {
color: #5c6470;
}
.brand-mark {
width: 40px;
height: 40px;
border-radius: var(--radius-md);
background: linear-gradient(135deg, var(--orange-400) 0%, var(--orange-600) 100%);
display: grid;
place-items: center;
font-size: 1.1rem;
box-shadow: 0 4px 16px var(--orange-glow);
flex-shrink: 0;
}
.brand-mark__img {
width: 100%;
height: 100%;
display: block;
border-radius: inherit;
}
.brand-sub {
display: block;
font-size: 0.68rem;
font-weight: 600;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.12em;
margin-top: 4px;
}
/* светлая тема: тёмный сайдбар — тот же оттенок, что и до смены --muted в :root */
body[data-theme="light"] .sidebar .brand-sub {
color: #5c6470;
}
.sidebar-nav {
flex: 1;
overflow-y: auto;
padding: 4px 0 12px;
scrollbar-width: thin;
scrollbar-color: rgba(249, 115, 22, 0.35) transparent;
}
.menu {
display: flex;
flex-direction: column;
gap: 4px;
}
.menu-cluster-block {
margin: 8px 0 4px;
padding: 10px;
border-radius: var(--radius-md);
border: 1px solid rgba(249, 115, 22, 0.2);
background: rgba(249, 115, 22, 0.06);
position: sticky;
top: 0;
}
.menu-cluster-block-head {
margin-bottom: 4px;
}
.menu-text-cluster {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 3px;
line-height: 1.2;
}
.menu-cluster-eyebrow {
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.12em;
color: #fdba74;
opacity: 0.95;
}
.menu-link.active .menu-cluster-eyebrow {
color: #ffedd5;
}
.menu-cluster-id {
font-size: 0.86rem;
font-weight: 600;
letter-spacing: -0.02em;
color: inherit;
}
.menu-link {
display: flex;
align-items: center;
gap: 12px;
color: #cbd5e1;
text-decoration: none;
padding: 10px 12px;
border-radius: var(--radius-md);
font-size: 0.9rem;
font-weight: 500;
border: 1px solid transparent;
transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}
.menu-icon {
width: 20px;
height: 20px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
color: inherit;
opacity: 0.72;
}
.menu-icon svg {
width: 100%;
height: 100%;
display: block;
}
.menu-icon i {
font-size: 0.95rem;
line-height: 1;
}
.menu-text {
flex: 1;
min-width: 0;
line-height: 1.35;
}
.menu-link:hover {
background: var(--hover);
color: #fff;
}
.menu-link:hover .menu-icon {
opacity: 0.92;
}
.menu-link.active {
background: linear-gradient(90deg, var(--accent-soft), rgba(249, 115, 22, 0.04));
color: #fff;
border-color: var(--accent-border);
box-shadow: 0 0 0 1px rgba(249, 115, 22, 0.08);
}
.menu-link.active .menu-icon {
opacity: 1;
color: var(--orange-200);
}
/* --- Sidebar profile band (avatar + dropdown), pinned to bottom --- */
.sidebar-user-band {
flex-shrink: 0;
margin-top: auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
padding: 12px 0 10px;
}
.sidebar-user-hr {
width: 100%;
border: none;
border-top: 1px solid rgba(255, 255, 255, 0.08);
margin: 0;
}
.sidebar-user-menu {
position: relative;
display: flex;
justify-content: center;
width: 100%;
}
.sidebar-user-avatar-btn {
display: grid;
place-items: center;
padding: 0;
border: 2px solid rgba(249, 115, 22, 0.35);
border-radius: 50%;
background: rgba(15, 23, 42, 0.6);
cursor: pointer;
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
transition: border-color 0.2s ease, transform 0.15s ease;
}
.sidebar-user-avatar-btn:hover,
.sidebar-user-avatar-btn:focus-visible {
border-color: rgba(249, 115, 22, 0.65);
outline: none;
}
.sidebar-user-avatar-btn:active {
transform: scale(0.98);
}
.sidebar-user-avatar-img {
width: 44px;
height: 44px;
border-radius: 50%;
object-fit: cover;
display: block;
background: rgba(30, 41, 59, 0.9);
}
.sidebar-user-dropdown {
display: none;
position: absolute;
left: 0;
right: 0;
bottom: calc(100% + 10px);
margin: 0 auto;
width: min(240px, 92vw);
padding: 8px 0;
list-style: none;
border-radius: var(--radius-md);
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(15, 23, 42, 0.98);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
z-index: 40;
}
.sidebar-user-dropdown.is-open {
display: block;
}
.sidebar-user-dropdown__head {
padding: 8px 14px 6px;
}
.sidebar-user-dropdown__name {
display: block;
font-weight: 700;
font-size: 0.92rem;
color: #f8fafc;
}
.sidebar-user-dropdown__meta {
font-size: 0.78rem;
}
.sidebar-user-dropdown__sep {
border: none;
border-top: 1px solid rgba(255, 255, 255, 0.08);
margin: 6px 0;
}
.sidebar-user-dropdown__link {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
color: #e2e8f0;
text-decoration: none;
font-size: 0.88rem;
border: none;
background: transparent;
width: 100%;
text-align: left;
cursor: pointer;
transition: background 0.15s ease;
}
.sidebar-user-dropdown__link:hover {
background: rgba(249, 115, 22, 0.12);
color: #fff;
}
.sidebar-user-dropdown__link i {
width: 18px;
opacity: 0.85;
}
/* Profile pages */
.profile-me-layout {
display: flex;
flex-wrap: wrap;
gap: 24px;
align-items: flex-start;
}
.profile-me-avatar-wrap {
flex-shrink: 0;
}
.profile-me-avatar {
width: 128px;
height: 128px;
border-radius: 50%;
object-fit: cover;
border: 3px solid rgba(249, 115, 22, 0.35);
background: rgba(30, 41, 59, 0.9);
}
.profile-dl {
margin: 0;
display: grid;
grid-template-columns: auto 1fr;
gap: 8px 20px;
font-size: 0.92rem;
}
.profile-dl dt {
margin: 0;
color: var(--muted);
font-weight: 600;
}
.profile-dl dd {
margin: 0;
}
.profile-me-bio {
white-space: pre-wrap;
}
.profile-edit-form .profile-edit-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: center;
}
.profile-avatar-layout {
display: grid;
grid-template-columns: minmax(200px, 280px) 1fr;
gap: 28px;
align-items: start;
}
@media (max-width: 820px) {
.profile-avatar-layout {
grid-template-columns: 1fr;
}
}
.profile-avatar-viewport-wrap {
display: flex;
justify-content: center;
}
.profile-avatar-viewport {
position: relative;
width: 280px;
height: 280px;
border-radius: 50%;
overflow: hidden;
margin: 0 auto;
border: 3px solid rgba(249, 115, 22, 0.35);
background: rgba(30, 41, 59, 0.6);
}
.profile-avatar-display-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.profile-avatar-display-img.is-hidden {
display: none;
}
.profile-avatar-edit-layer {
position: absolute;
inset: 0;
cursor: grab;
touch-action: none;
}
.profile-avatar-edit-layer:active {
cursor: grabbing;
}
.profile-avatar-edit-layer img {
position: absolute;
left: 0;
top: 0;
max-width: none;
max-height: none;
user-select: none;
pointer-events: none;
}
.profile-avatar-controls {
margin-top: 14px;
max-width: 280px;
margin-left: auto;
margin-right: auto;
}
.profile-avatar-zoom-label {
display: flex;
flex-direction: column;
gap: 8px;
font-size: 0.85rem;
font-weight: 600;
color: var(--text, #e8e8ef);
}
.profile-avatar-zoom-label input[type="range"] {
width: 100%;
}
.profile-avatar-drag-hint {
margin: 10px 0 0;
}
.profile-avatar-drop {
position: relative;
border: 2px dashed rgba(249, 115, 22, 0.35);
border-radius: var(--radius-md);
padding: 28px 20px;
text-align: center;
cursor: pointer;
background: rgba(15, 23, 42, 0.35);
transition: border-color 0.2s ease, background 0.2s ease;
}
.profile-avatar-drop:hover,
.profile-avatar-drop.is-dragover {
border-color: rgba(249, 115, 22, 0.65);
background: rgba(249, 115, 22, 0.08);
}
.profile-avatar-drop:focus-visible {
outline: 2px solid var(--orange-400);
outline-offset: 2px;
}
.profile-avatar-file-input {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
}
.profile-avatar-drop-inner {
pointer-events: none;
}
.profile-avatar-drop-icon {
font-size: 2rem;
color: var(--orange-400);
margin-bottom: 8px;
}
.profile-avatar-browse {
color: var(--orange-300);
text-decoration: underline;
}
.profile-avatar-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 18px;
}
/* Sidebar: hover/active/фокусы для top-level (сброс button vs a.menu-link — сразу после глобального `button` ниже по файлу) */
.sidebar a.menu-link:hover,
.sidebar .menu-accordion__head:hover {
background: rgba(255, 255, 255, 0.06) !important;
color: #fff !important;
filter: none;
}
.sidebar a.menu-link:hover .menu-icon,
.sidebar .menu-accordion__head:hover .menu-icon {
opacity: 0.92;
}
.sidebar .menu-accordion__head:hover .menu-accordion__toggle {
opacity: 0.92;
}
.sidebar a.menu-link.active {
background: linear-gradient(90deg, rgba(249, 115, 22, 0.14), rgba(249, 115, 22, 0.04)) !important;
color: #fff !important;
border-color: rgba(251, 146, 60, 0.45) !important;
box-shadow: 0 0 0 1px rgba(249, 115, 22, 0.08);
filter: none;
}
.sidebar a.menu-link.active .menu-icon,
.sidebar a.menu-link.active .menu-accordion__toggle {
opacity: 1;
color: #fed7aa;
}
.sidebar .muted { color: rgba(203, 213, 225, 0.7); }
.sidebar .menu-sublink { color: #e6edf7; }
.sidebar .menu-eyebrow { color: #94a3b8; }
.sidebar .menu-sublink:hover { background: rgba(249, 115, 22, 0.1); }
.sidebar .menu-sublink.active { color: #fff; }
/* Светлая тема: подменю в сайдбаре — тот же «тёмный» вид, что и без data-theme=light (не светлая плашка) */
body[data-theme="light"] .sidebar .menu-accordion__panel {
background: rgba(0, 0, 0, 0.22);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: var(--radius-sm);
padding: 6px 6px 8px;
margin: 2px 0 6px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-sublink,
body[data-theme="light"] .sidebar .menu-accordion__panel a.menu-sublink,
body[data-theme="light"] .sidebar .menu-accordion__panel a.menu-link {
color: #e6edf7;
}
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-sublink:hover {
background: rgba(249, 115, 22, 0.1);
color: #fff;
}
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-sublink.active,
body[data-theme="light"] .sidebar .menu-accordion__panel a.menu-sublink.active {
color: #fff;
font-weight: 600;
background: linear-gradient(90deg, rgba(249, 115, 22, 0.2), rgba(249, 115, 22, 0.06));
box-shadow: 0 0 0 1px rgba(249, 115, 22, 0.12);
}
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-eyebrow,
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-tree-eyebrow {
color: #94a3b8;
}
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-nested--tree,
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-tree-block {
border-left-color: rgba(148, 163, 184, 0.3);
}
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-tree-subl,
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-tree-subl a {
color: rgba(203, 213, 225, 0.9);
}
body[data-theme="light"] .sidebar .menu-accordion__panel .muted,
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-tree-subl a:hover {
color: rgba(203, 213, 225, 0.75);
}
body[data-theme="light"] .sidebar .menu-accordion__panel a.menu-tree-cluster,
body[data-theme="light"] .sidebar .menu-accordion__panel .menu-tree-block a {
color: #e6edf7;
}
/* Вложенный аккордеон (имя кластера) — как в тёмной теме */
body[data-theme="light"] .sidebar .menu-accordion--cluster > .menu-accordion__panel {
background: transparent;
border: 0;
box-shadow: none;
margin: 0 0 0.1rem 0;
padding: 0 0 0.15rem 0.15rem;
}
body[data-theme="light"] .sidebar .menu-accordion--cluster > .menu-accordion__head {
background: transparent !important;
border: 1px solid transparent !important;
color: #e6edf7 !important;
box-shadow: none !important;
border-radius: var(--radius-md);
margin: 0;
font-weight: 500;
filter: none !important;
}
body[data-theme="light"] .sidebar .menu-accordion--cluster > .menu-accordion__head:hover,
body[data-theme="light"] .sidebar .menu-accordion--cluster.is-active > .menu-accordion__head {
background: rgba(249, 115, 22, 0.1) !important;
color: #fff !important;
border-color: transparent !important;
filter: none !important;
}
/* Тёмный сайдбар: 3-й уровень (кластер) — как вложенная плашка */
.sidebar-clusters-tree {
position: relative;
display: flex;
flex-direction: column;
gap: 0.05rem;
}
.sidebar-clusters-tree::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 1rem;
width: 0;
background: rgba(148, 163, 184, 0.3);
pointer-events: none;
}
.menu-accordion--cluster {
margin: 0;
}
.menu-accordion.menu-accordion--cluster > .menu-accordion__head {
width: 100%;
min-height: 0;
box-sizing: border-box;
}
.menu-accordion--cluster + .menu-accordion--cluster {
margin-top: 0.15rem;
}
.menu-accordion--cluster .menu-accordion__head--cluster {
font-size: 0.9rem;
min-height: 0;
padding: 10px 12px;
border: 1px solid transparent;
border-radius: var(--radius-md);
font-weight: 500;
}
.menu-accordion--cluster .menu-accordion__head--cluster:hover {
background: rgba(249, 115, 22, 0.08) !important;
color: #fff !important;
}
.menu-accordion--cluster .menu-accordion__head--cluster .menu-icon {
width: 18px;
height: 18px;
opacity: 0.9;
}
.menu-accordion--cluster .menu-accordion__head--cluster .menu-text {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
/* Для кластера не подсвечиваем заголовок как active: активной должна быть только конечная страница */
.sidebar .menu-accordion--cluster.is-active > .menu-accordion__head {
background: rgba(255, 255, 255, 0.04) !important;
color: #e6edf7 !important;
border-color: rgba(255, 255, 255, 0.1) !important;
box-shadow: none !important;
}
.sidebar .menu-accordion--cluster.is-active > .menu-accordion__head .menu-icon,
.sidebar .menu-accordion--cluster.is-active > .menu-accordion__head .menu-accordion__toggle {
color: inherit !important;
opacity: 0.85 !important;
}
body[data-theme="light"] .sidebar .menu-accordion--cluster .menu-accordion__head--cluster .menu-icon,
body[data-theme="light"] .sidebar .menu-accordion--cluster .menu-accordion__head--cluster .menu-accordion__toggle {
color: #cbd5e1;
opacity: 0.85;
}
.content {
padding: 28px 32px 1rem;
max-width: 1520px;
width: 100%;
margin: 0 auto;
}
.page-header {
margin-bottom: 8px;
}
.page-header h1 {
margin: 0 0 8px;
font-size: clamp(1.5rem, 2.5vw, 2rem);
font-weight: 800;
letter-spacing: -0.03em;
color: var(--text);
}
.page-header--split {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
margin-bottom: 20px;
}
.page-header--split .page-header-text {
min-width: 0;
flex: 1 1 12rem;
}
.muted {
margin: 0;
color: var(--muted);
font-size: 0.95rem;
}
/* —— Home dashboard (modern bento) —— */
.dashboard-page {
--dash-radius: 18px;
--dash-glow: 0 0 80px rgba(249, 115, 22, 0.12);
animation: dash-enter 0.5s ease both;
}
@keyframes dash-enter {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.dashboard-hero {
position: relative;
display: grid;
grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
align-items: stretch;
gap: 24px;
padding: 28px 28px 32px;
border-radius: var(--dash-radius);
border: 1px solid var(--card-border);
background:
linear-gradient(135deg, color-mix(in srgb, var(--card) 90%, #1a1410) 0%, var(--card) 100%),
linear-gradient(160deg, rgba(249, 115, 22, 0.1) 0%, transparent 55%);
box-shadow: var(--shadow-card), var(--dash-glow);
overflow: hidden;
margin-bottom: 24px;
}
body[data-theme="light"] .dashboard-hero {
background:
linear-gradient(135deg, #ffffff 0%, #faf6f1 100%),
linear-gradient(160deg, rgba(249, 115, 22, 0.14) 0%, transparent 50%);
}
/* Правая зона: по умолчанию flex; с CTA см. .dashboard-hero--with-actions */
.dashboard-hero-aside {
position: relative;
z-index: 1;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
align-self: stretch;
gap: 16px 20px;
min-width: 0;
min-height: 120px;
}
/* Dashboard-only hero mode: aside acts as decorative background behind text content. */
.dashboard-page .dashboard-hero:not(.dashboard-hero--with-actions) .dashboard-hero-aside {
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
}
.dashboard-page .dashboard-hero:not(.dashboard-hero--with-actions) .dashboard-hero-aside .dashboard-hero-visual {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.dashboard-hero-aside .dashboard-hero-visual {
flex: 1 1 120px;
min-width: 0;
min-height: 120px;
}
.dashboard-hero-aside .dashboard-hero-actions-col {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: flex-end;
min-width: 0;
}
/* CTA: орбы — подложка на весь aside; кнопки — по вертикали по центру, вправо */
.dashboard-hero--with-actions .dashboard-hero-aside {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
flex-wrap: nowrap;
min-height: 120px;
height: 100%;
box-sizing: border-box;
}
.dashboard-hero--with-actions .dashboard-hero-aside .dashboard-hero-visual {
position: absolute;
inset: 0;
flex: none;
width: 100%;
min-width: 0;
min-height: 120px;
height: 100%;
pointer-events: none;
}
.dashboard-hero--with-actions .dashboard-hero-aside .dashboard-hero-actions-col {
position: relative;
z-index: 2;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
max-width: 100%;
box-sizing: border-box;
padding: 0 0 0 8px;
flex: 0 0 auto;
margin: 0;
width: auto;
}
.dashboard-hero-inner { position: relative; z-index: 2; max-width: 560px; align-self: start; }
.dashboard-hero-kicker {
margin: 0 0 8px;
font-size: 0.68rem;
font-weight: 800;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--orange-500);
}
.dashboard-hero-title {
margin: 0 0 10px;
font-size: clamp(1.75rem, 3.5vw, 2.35rem);
font-weight: 900;
letter-spacing: -0.04em;
color: var(--text);
line-height: 1.1;
}
.dashboard-hero-lead {
margin: 0;
font-size: 1.02rem;
line-height: 1.55;
color: var(--muted);
max-width: 42ch;
}
.dashboard-hero-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
gap: 10px;
margin-top: 0;
}
.dashboard-hero-actions--roles {
gap: 10px;
}
.dashboard-hero-actions--roles .cta-button {
box-sizing: border-box;
min-height: 2.625rem;
padding: 0.625rem 1.125rem;
font-size: 0.95rem;
}
.cta-button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2.5rem;
padding: 0.625rem 1rem;
border-radius: var(--radius-md);
border: 1px solid rgba(234, 88, 12, 0.6);
background: linear-gradient(135deg, var(--orange-400) 0%, var(--orange-500) 40%, var(--orange-600) 100%);
color: #fff;
font-weight: 600;
font-size: 0.95rem;
text-decoration: none;
font-family: inherit;
box-shadow: 0 2px 12px rgba(249, 115, 22, 0.25);
transition: var(--form-transition);
white-space: nowrap;
cursor: pointer;
}
.cta-button:hover {
filter: brightness(1.06);
box-shadow: 0 4px 18px rgba(249, 115, 22, 0.35);
color: #fff;
}
.cta-button:focus-visible {
outline: none;
box-shadow: var(--form-focus-ring), 0 2px 12px rgba(249, 115, 22, 0.25);
color: #fff;
}
.cta-button--secondary {
background: transparent;
border-color: var(--input-border);
color: var(--text);
box-shadow: none;
}
.cta-button--secondary:hover {
background: var(--hover);
border-color: var(--orange-400);
color: var(--text);
filter: none;
}
.cta-button--secondary:focus-visible {
box-shadow: var(--form-focus-ring);
}
.cluster-list-empty {
padding: 1.5rem 0 0.5rem;
}
.cluster-list-empty p {
margin: 0 0 0.75rem;
}
.dashboard-hero-visual { position: relative; min-height: 120px; }
.dashboard-hero-orbs {
position: absolute;
inset: -20% -10% 20% 10%;
background:
radial-gradient(ellipse 70% 60% at 80% 20%, rgba(249, 115, 22, 0.35), transparent 55%),
radial-gradient(ellipse 50% 40% at 20% 80%, rgba(234, 88, 12, 0.15), transparent 50%);
border-radius: 50%;
filter: blur(0.5px);
pointer-events: none;
opacity: 0.9;
}
/* shared hero: macros/page-hero.xhtml adds .app-page-hero (same as .dashboard-hero) */
/* Auth: hero is first child in .public-card, bleed to card edges on top */
.public-card > .app-page-hero,
.public-card > .dashboard-hero {
margin: -28px -26px 24px;
max-width: none;
width: auto;
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.public-card > .app-page-hero,
.public-card > .dashboard-hero {
grid-template-columns: 1fr;
}
.public-card > .app-page-hero .dashboard-hero-inner,
.public-card > .dashboard-hero .dashboard-hero-inner,
.public-card > .app-page-hero .dashboard-hero-lead,
.public-card > .dashboard-hero .dashboard-hero-lead {
max-width: none;
width: 100%;
}
.public-card > .app-page-hero .dashboard-hero-aside,
.public-card > .dashboard-hero .dashboard-hero-aside {
width: 100%;
min-height: 72px;
justify-content: flex-start;
align-items: stretch;
}
.public-layout[data-page="login"] .public-card > .app-page-hero .dashboard-hero-aside,
.public-layout[data-page="login"] .public-card > .dashboard-hero .dashboard-hero-aside,
.public-layout[data-page="register"] .public-card > .app-page-hero .dashboard-hero-aside,
.public-layout[data-page="register"] .public-card > .dashboard-hero .dashboard-hero-aside,
.public-layout[data-page="reset-password"] .public-card > .app-page-hero .dashboard-hero-aside,
.public-layout[data-page="reset-password"] .public-card > .dashboard-hero .dashboard-hero-aside {
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
}
.public-layout[data-page="login"] .public-card > .app-page-hero .dashboard-hero-aside .dashboard-hero-visual,
.public-layout[data-page="login"] .public-card > .dashboard-hero .dashboard-hero-aside .dashboard-hero-visual,
.public-layout[data-page="register"] .public-card > .app-page-hero .dashboard-hero-aside .dashboard-hero-visual,
.public-layout[data-page="register"] .public-card > .dashboard-hero .dashboard-hero-aside .dashboard-hero-visual,
.public-layout[data-page="reset-password"] .public-card > .app-page-hero .dashboard-hero-aside .dashboard-hero-visual,
.public-layout[data-page="reset-password"] .public-card > .dashboard-hero .dashboard-hero-aside .dashboard-hero-visual {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.dashboard-stat-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 14px;
margin-bottom: 18px;
}
.dashboard-stat {
position: relative;
display: flex;
align-items: flex-start;
gap: 14px;
padding: 18px 18px 20px;
border-radius: var(--radius-lg);
border: 1px solid var(--card-border);
background: var(--card);
box-shadow: var(--shadow-card);
overflow: hidden;
transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.dashboard-stat::before {
content: "";
position: absolute;
inset: 0 0 auto 0;
height: 3px;
background: linear-gradient(90deg, var(--orange-500), var(--orange-400));
opacity: 0.65;
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
pointer-events: none;
}
.dashboard-stat:hover {
border-color: rgba(249, 115, 22, 0.3);
transform: translateY(-2px);
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(249, 115, 22, 0.1);
}
.dashboard-stat-icon {
width: 44px;
height: 44px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
color: #fff;
background: linear-gradient(145deg, #fb923c, #ea580c);
box-shadow: 0 6px 20px rgba(249, 115, 22, 0.28);
}
.dashboard-stat-icon svg { width: 24px; height: 24px; }
.dashboard-stat-body { min-width: 0; }
.dashboard-stat-label {
display: block;
font-size: 0.7rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--muted);
margin-bottom: 4px;
}
.dashboard-stat-value {
margin: 0;
font-size: clamp(1.5rem, 2.5vw, 1.85rem);
font-weight: 800;
font-variant-numeric: tabular-nums;
letter-spacing: -0.03em;
color: var(--text);
line-height: 1.1;
}
.dashboard-stat-hint {
display: block;
margin-top: 6px;
font-size: 0.72rem;
font-weight: 600;
color: var(--muted);
opacity: 0.9;
}
/* —— Dashboard: live trend strip (charts + head-up values) —— */
.dashboard-trends-wrap {
margin-bottom: 22px;
}
.dashboard-trends-intro {
margin-bottom: 14px;
padding: 0 2px;
}
.dashboard-trends-heading {
margin: 0 0 6px;
font-size: 1.05rem;
font-weight: 800;
letter-spacing: -0.03em;
color: var(--text);
}
.dashboard-trends-sub {
margin: 0;
max-width: 64ch;
font-size: 0.9rem;
line-height: 1.5;
color: var(--muted);
}
.dashboard-trends {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
align-items: stretch;
}
.dashboard-trend {
--trend-line: #f97316;
position: relative;
display: flex;
flex-direction: column;
border-radius: 20px;
padding: 0;
min-height: 0;
overflow: hidden;
border: 1px solid var(--card-border);
background:
linear-gradient(160deg, color-mix(in srgb, var(--trend-line) 8%, var(--card)) 0%, var(--card) 55%),
var(--card);
box-shadow:
0 0 0 1px color-mix(in srgb, var(--trend-line) 10%, transparent),
0 20px 48px rgba(0, 0, 0, 0.2),
inset 0 1px 0 color-mix(in srgb, #fff 5%, transparent);
transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.2s ease;
}
body[data-theme="light"] .dashboard-trend {
box-shadow:
0 0 0 1px color-mix(in srgb, var(--trend-line) 12%, var(--card-border)),
0 16px 40px rgba(0, 0, 0, 0.07),
inset 0 1px 0 #fff;
}
.dashboard-trend:hover {
transform: translateY(-3px);
border-color: color-mix(in srgb, var(--trend-line) 32%, var(--card-border));
box-shadow:
0 0 0 1px color-mix(in srgb, var(--trend-line) 22%, transparent),
0 24px 56px rgba(0, 0, 0, 0.22);
}
.dashboard-trend[data-trend="cpu"] { --trend-line: #fb923c; }
.dashboard-trend[data-trend="ram"] { --trend-line: #a78bfa; }
.dashboard-trend[data-trend="pods"] { --trend-line: #2dd4bf; }
.dashboard-trend__accent {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
border-radius: 20px 0 0 20px;
background: linear-gradient(180deg, var(--trend-line), color-mix(in srgb, var(--trend-line) 40%, #000));
opacity: 0.9;
pointer-events: none;
}
.dashboard-trend__top {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: start;
gap: 12px 14px;
padding: 16px 18px 10px 20px;
}
.dashboard-trend__icon {
width: 42px;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 14px;
color: var(--trend-line);
background: color-mix(in srgb, var(--trend-line) 16%, var(--bg-panel));
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--trend-line) 25%, transparent);
}
.dashboard-trend__icon svg { width: 22px; height: 22px; }
.dashboard-trend__kicker {
display: block;
font-size: 0.62rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.19em;
color: var(--muted);
margin-bottom: 4px;
}
.dashboard-trend__headline {
display: flex;
flex-wrap: nowrap;
align-items: baseline;
justify-content: space-between;
gap: 4px 12px;
width: 100%;
}
.dashboard-trend__meta {
min-width: 0;
width: 100%;
}
.dashboard-trend__name {
font-size: 1.02rem;
font-weight: 800;
letter-spacing: -0.03em;
color: var(--text);
}
.dashboard-trend__value {
font-size: 1.35rem;
font-weight: 800;
font-variant-numeric: tabular-nums;
letter-spacing: -0.04em;
color: var(--trend-line);
min-width: 3.2ch;
text-align: right;
}
.dashboard-trend__pill {
align-self: start;
font-size: 0.6rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.12em;
color: var(--muted);
padding: 5px 10px;
border-radius: 999px;
border: 1px solid var(--border);
background: var(--bg-panel);
white-space: nowrap;
}
.dashboard-trend__plot {
position: relative;
z-index: 1;
margin-top: 2px;
padding: 0 18px 16px 20px;
flex: 1;
display: flex;
flex-direction: column;
min-height: 132px;
background: transparent;
border-radius: 0;
}
.dashboard-trend__plot-inner {
position: relative;
flex: 1;
min-height: 120px;
border-radius: 0;
overflow: hidden;
background: transparent;
box-shadow: none;
}
body[data-theme="light"] .dashboard-trend__plot-inner {
background: transparent;
box-shadow: none;
}
.dashboard-trend__plot-inner::after {
content: "";
position: absolute;
left: 8px;
right: 8px;
top: 10px;
bottom: 8px;
background-image: repeating-linear-gradient(
0deg,
color-mix(in srgb, var(--text) 6%, transparent) 0,
color-mix(in srgb, var(--text) 6%, transparent) 1px,
transparent 1px,
transparent 22px
);
border-radius: 6px;
pointer-events: none;
mix-blend-mode: soft-light;
opacity: 0.14;
z-index: 0;
}
.dashboard-trend__plot-inner canvas {
position: relative;
z-index: 1;
width: 100% !important;
height: 100% !important;
display: block;
background: var(--card) !important;
border: 0 !important;
border-radius: 0 !important;
}
.dashboard-panel {
border-radius: var(--dash-radius);
border: 1px solid var(--card-border);
background: var(--card);
box-shadow: var(--shadow-card);
padding: 22px 24px 24px;
margin-bottom: 20px;
}
.dashboard-page > .dashboard-panel:last-child { margin-bottom: 0; }
.dashboard-panel--primary { padding-bottom: 18px; }
.dashboard-panel-h { margin-bottom: 16px; }
.dashboard-panel-title {
margin: 0 0 4px;
font-size: 1.05rem;
font-weight: 800;
letter-spacing: -0.02em;
color: var(--text);
}
.dashboard-panel-sub { margin: 0; font-size: 0.9rem; color: var(--muted); line-height: 1.45; max-width: 56ch; }
.dashboard-panel-h { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.dashboard-panel-badge {
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
padding: 4px 10px;
border-radius: 999px;
border: 1px solid var(--border);
color: var(--muted);
background: var(--bg-panel);
white-space: nowrap;
}
.dashboard-panel .dashboard-panel-h h2 { margin: 0; }
.dashboard-panel .form-actions { border-top: none; padding-top: 0; margin-top: 4px; }
.dashboard-main-chart {
position: relative;
width: 100%;
height: 280px;
margin: 0 -4px 0 0;
overflow: hidden;
border-radius: var(--radius-md);
background: var(--card);
}
.dashboard-main-chart canvas {
display: block;
width: 100% !important;
height: 100% !important;
max-width: 100%;
}
#stats-chart {
background: var(--card) !important;
border: 0 !important;
border-radius: 0 !important;
}
.dashboard-lower {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
align-items: start;
margin-bottom: 8px;
}
@media (max-width: 1100px) {
.dashboard-lower { grid-template-columns: 1fr; }
}
.dashboard-form-row { display: block; margin: 0; }
.dashboard-form-cluster {
display: flex;
flex-direction: column;
gap: 6px;
max-width: 200px;
margin-bottom: 12px;
}
.dashboard-inline-label { font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.dashboard-form-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 10px; }
.dashboard-grow { flex: 1 1 200px; min-width: 180px; }
.dashboard-audit-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin-bottom: 10px; }
.dashboard-audit-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin: 0 0 12px; }
.dashboard-audit-limits { display: flex; flex-direction: column; gap: 6px; min-width: 100px; }
.dashboard-audit-limits select { min-width: 5.5rem; }
.audit-pagination { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-left: auto; }
.audit-pagination__nav { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.audit-page-info { min-width: 10.5rem; text-align: center; font-size: 0.82rem; }
.audit-total-info { font-size: 0.82rem; }
@media (max-width: 720px) { .audit-pagination { margin-left: 0; } }
.audit-logs-output { margin-top: 4px; }
/* Таблица текущей страницы без внутреннего скролла; листается страница, не контейнер */
.audit-logs-table-wrap { max-height: none; overflow: visible; border-radius: var(--radius-md); border: 1px solid var(--border); }
.audit-logs-table { font-size: 0.88rem; margin: 0; table-layout: fixed; width: 100%; }
.audit-logs-table th { position: static; z-index: auto; background: var(--bg-panel); }
.audit-col-time { width: 7.5rem; max-width: 9.5rem; }
.audit-col-user { max-width: 10rem; word-break: break-word; }
.audit-col-user span { display: block; max-width: 10rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.audit-col-action { max-width: 220px; word-break: break-word; }
.audit-col-entity { max-width: 140px; word-break: break-word; }
.audit-col-details { max-width: 320px; vertical-align: top; }
.audit-details { margin: 0; }
.audit-details > summary {
cursor: pointer;
list-style: none;
font-size: 0.82rem;
color: var(--text-muted, #94a3b8);
line-height: 1.35;
}
.audit-details > summary::-webkit-details-marker { display: none; }
.audit-details > summary::before { content: "▸ "; opacity: 0.7; }
.audit-details[open] > summary::before { content: "▾ "; }
.audit-details-pre {
margin: 0.4rem 0 0;
padding: 0.5rem 0.55rem;
font-size: 0.72rem;
line-height: 1.35;
max-height: 12rem;
overflow: auto;
border-radius: 6px;
border: 1px solid var(--border);
background: color-mix(in srgb, var(--bg) 92%, var(--card));
color: var(--text);
white-space: pre-wrap;
word-break: break-word;
}
/* Admin: /users */
.users-table-wrap { margin-top: 4px; }
.users-admin-table { font-size: 0.85rem; }
.users-admin-table th, .users-admin-table td { vertical-align: top; word-break: break-word; }
.users-admin-table tbody tr.users-row--clickable { cursor: pointer; }
.users-admin-table tbody tr.user-row--removed { color: var(--text-muted, #888); }
.users-admin-table tbody tr.user-row--removed td { opacity: 0.88; }
.profile-removed-banner {
margin: 0 0 1rem;
padding: 0.65rem 1rem;
border-radius: 8px;
background: color-mix(in srgb, var(--text-muted) 12%, var(--bg-panel));
color: var(--text-muted, #a0a0a0);
font-size: 0.9rem;
}
.profile-admin-actions { margin-bottom: 1rem; }
.profile-admin-actions-inner { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.profile-page--removed .profile-me-layout { filter: grayscale(0.9); opacity: 0.82; }
.users-col-username { max-width: 12rem; }
.users-td-view { white-space: nowrap; text-align: center; }
.users-admin-table thead th { background: color-mix(in srgb, var(--orange-500) 12%, var(--bg-panel)); }
.users-admin-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--card) 88%, var(--bg-panel)); }
.users-admin-table tbody tr:hover { background: color-mix(in srgb, var(--accent-soft) 68%, transparent); }
.users-admin-table tbody tr.users-row--clickable:hover { background: color-mix(in srgb, var(--accent-soft) 88%, var(--bg-panel)) !important; }
.users-admin-table tbody tr.user-row--removed:hover { background: color-mix(in srgb, var(--card) 80%, var(--bg-panel)) !important; }
.admin-user-detail { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.admin-user-detail__title { margin: 0 0 0.5rem; font-size: 1.1rem; }
.admin-user-kvgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px 12px; margin-bottom: 1rem; }
.admin-kv { display: flex; flex-direction: column; gap: 2px; }
.admin-kv__k { font-size: 0.65rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.admin-kv__v { font-size: 0.88rem; }
.admin-subh { margin: 1rem 0 0.5rem; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.user-detail-page .user-detail-title { margin: 0 0 8px; }
.user-detail-page .user-admin-actions { margin: 0 0 16px; }
.admin-section-card {
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: color-mix(in srgb, var(--card) 92%, var(--bg-panel));
padding: 12px 14px;
margin-bottom: 12px;
}
.admin-section-card--profile {
background: linear-gradient(140deg, color-mix(in srgb, var(--orange-500) 9%, var(--card)) 0%, var(--card) 100%);
border-color: color-mix(in srgb, var(--orange-500) 22%, var(--border));
}
.admin-section-card .admin-subh { margin-top: 0; }
.admin-json-block {
font-size: 0.75rem; line-height: 1.35; max-height: 12rem; overflow: auto; padding: 0.5rem; border-radius: 6px;
border: 1px solid var(--border);
background: color-mix(in srgb, var(--bg) 92%, var(--card));
color: var(--text);
white-space: pre-wrap; word-break: break-word; margin: 0 0 0.5rem;
}
.admin-user-detail__grid .table-wrap { margin-top: 0.35rem; }
.dashboard-code-block {
border-radius: var(--radius-md);
border: 1px solid var(--border);
background: color-mix(in srgb, var(--bg) 92%, var(--card)) !important;
color: var(--text);
max-height: 280px;
overflow: auto;
}
@media (max-width: 1200px) {
.dashboard-hero { grid-template-columns: 1fr; }
.dashboard-hero-aside {
justify-content: flex-end;
min-height: 80px;
margin-top: 4px;
}
.dashboard-hero--with-actions .dashboard-hero-aside {
height: auto;
min-height: 100px;
align-items: flex-end;
}
.dashboard-hero--with-actions .dashboard-hero-aside .dashboard-hero-visual {
min-height: 80px;
}
.dashboard-hero--with-actions .dashboard-hero-actions,
.dashboard-hero-aside .dashboard-hero-actions-col,
.dashboard-hero-aside .dashboard-hero-actions {
justify-content: flex-end;
}
.dashboard-hero-aside .dashboard-hero-visual,
.dashboard-hero-visual { min-height: 80px; }
.dashboard-stat-grid { grid-template-columns: repeat(2, 1fr); }
.dashboard-trends { grid-template-columns: 1fr; }
.dashboard-main-chart { height: 240px; }
}
@media (max-width: 640px) {
.dashboard-stat-grid { grid-template-columns: 1fr; }
.content .dashboard-page { margin: 0 -4px; }
.dashboard-hero { padding: 22px 18px; }
.dashboard-panel { padding: 18px; }
.dashboard-trend__top { padding: 14px 14px 8px 18px; }
.dashboard-trend__plot { padding: 0 8px 12px 16px; }
}
/* —— Cards —— */
.card-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 14px;
margin-top: 20px;
}
.card {
margin-top: 16px;
background: var(--card);
border: 1px solid var(--card-border);
border-radius: var(--radius-lg);
padding: 20px 22px;
box-shadow: var(--shadow-card);
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.card:hover {
transform: translateY(-2px);
border-color: rgba(249, 115, 22, 0.22);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28), 0 0 0 1px rgba(249, 115, 22, 0.06);
}
body[data-theme="light"] .card:hover {
box-shadow: 0 8px 28px rgba(26, 29, 36, 0.08), 0 0 0 1px rgba(249, 115, 22, 0.12);
}
.card h2, .card h3 {
margin: 0 0 14px;
font-weight: 700;
letter-spacing: -0.02em;
}
/* —— Forms (AppsTemplate-style controls, orange accents) —— */
form { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
/* Text fields & selects */
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="hidden"]):not([type="file"]):not([type="image"]):not([type="range"]),
select,
textarea {
border-radius: 0.5rem;
border: 2px solid var(--input-border);
padding: 0.5rem 0.75rem;
min-height: 2.5rem;
/* longhands: краткое `background` у select съедает chevron; color-scheme + фон/текст согласованы с темой */
background-color: var(--form-check-bg);
background-image: none;
color: var(--text);
color-scheme: inherit;
font-family: inherit;
font-size: 1rem;
line-height: 1.5;
transition: var(--form-transition);
}
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="hidden"]):not([type="file"]):not([type="image"]):not([type="range"]),
select,
textarea {
min-width: min(190px, 100%);
}
textarea {
min-height: 4rem;
resize: vertical;
}
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="hidden"]):not([type="file"]):not([type="image"]):not([type="range"])::placeholder,
textarea::placeholder {
color: var(--muted);
opacity: 1;
}
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="hidden"]):not([type="file"]):not([type="image"]):not([type="range"]):hover,
select:hover,
textarea:hover {
border-color: color-mix(in srgb, var(--input-border) 65%, var(--orange-400));
}
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="hidden"]):not([type="file"]):not([type="image"]):not([type="range"]):focus,
select:focus,
textarea:focus {
outline: none;
border-color: var(--orange-500);
box-shadow: var(--form-focus-ring);
background-color: var(--form-check-bg);
transform: translateY(-1px);
}
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="hidden"]):not([type="file"]):not([type="image"]):not([type="range"]):disabled,
select:disabled,
textarea:disabled {
opacity: 0.6;
cursor: not-allowed;
background-color: color-mix(in srgb, var(--form-check-bg) 88%, var(--muted));
background-image: none;
}
select {
appearance: none;
-webkit-appearance: none;
padding-right: 2.5rem;
background-color: var(--form-check-bg);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%2394a3b8' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.65rem center;
background-size: 16px 12px;
cursor: pointer;
}
body[data-theme="light"] select {
background-color: var(--form-check-bg);
color: var(--text);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23374151' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}
select:focus {
background-color: var(--form-check-bg);
color: var(--text);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23f97316' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}
select[multiple] {
background-image: none;
padding-right: 0.75rem;
min-height: 5rem;
}
/* Chrome/Safari autofill — иначе остаётся тёмный fill и пропадает контраст с var(--text) */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
-webkit-text-fill-color: var(--text);
caret-color: var(--text);
box-shadow: 0 0 0 1000px var(--form-check-bg) inset;
transition: background-color 9999s ease-out 0s;
}
/* Buttons (primary chrome) */
button {
border-radius: var(--radius-md);
border: 1px solid rgba(234, 88, 12, 0.6);
padding: 0.625rem 1rem;
min-height: 2.5rem;
background: linear-gradient(135deg, var(--orange-400) 0%, var(--orange-500) 40%, var(--orange-600) 100%);
cursor: pointer;
color: #fff;
font-weight: 600;
font-size: 0.95rem;
font-family: inherit;
box-shadow: 0 2px 12px rgba(249, 115, 22, 0.25);
transition: var(--form-transition);
}
button:hover {
filter: brightness(1.06);
box-shadow: 0 4px 18px rgba(249, 115, 22, 0.35);
}
button:focus-visible {
outline: none;
box-shadow: var(--form-focus-ring), 0 2px 12px rgba(249, 115, 22, 0.25);
}
/* Сайдбар: top-level `button.menu-link` = строка `a.menu-link` (глобальный `button` идёт выше — этот блок ниже, перетирает градиент/тени); отличается только .menu-accordion__toggle (вниз/вверх) */
.sidebar .menu-accordion__head,
.sidebar .menu-accordion > button.menu-link {
-webkit-appearance: none;
appearance: none;
display: flex;
align-items: center;
gap: 12px;
width: 100%;
min-height: 0;
padding: 10px 12px;
border-radius: var(--radius-md);
font-family: inherit;
font-size: 0.9rem;
font-weight: 500;
line-height: 1.35;
text-align: left;
color: #cbd5e1;
background: none;
background-image: none;
border: 1px solid transparent;
box-shadow: none;
cursor: pointer;
filter: none;
transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}
.sidebar .menu-accordion__head:hover {
filter: none;
box-shadow: none;
}
.sidebar .menu-accordion__head:focus {
outline: none;
}
.sidebar .menu-accordion__head:focus-visible {
outline: 2px solid rgba(249, 115, 22, 0.5);
outline-offset: 2px;
box-shadow: none;
filter: none;
}
/* Checkboxes & radios (AppsTemplate checkmark / dot) */
input[type="checkbox"],
input[type="radio"] {
appearance: none;
-webkit-appearance: none;
width: 1.25em;
height: 1.25em;
min-width: 1.25em;
margin: 0;
padding: 0;
border: 2px solid var(--input-border);
background-color: var(--form-check-bg);
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
transition: var(--form-transition);
vertical-align: middle;
flex-shrink: 0;
}
input[type="checkbox"] {
border-radius: 0.375em;
}
input[type="radio"] {
border-radius: 50%;
}
input[type="checkbox"]:hover,
input[type="radio"]:hover {
border-color: var(--orange-400);
}
input[type="checkbox"]:checked {
background-color: var(--orange-500);
border-color: var(--orange-500);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e");
background-size: 14px 14px;
}
input[type="radio"]:checked {
background-color: var(--orange-500);
border-color: var(--orange-500);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3ccircle cx='8' cy='8' r='4' fill='%23fff'/%3e%3c/svg%3e");
background-size: 12px 12px;
}
input[type="checkbox"]:focus,
input[type="radio"]:focus {
outline: none;
border-color: var(--orange-500);
box-shadow: var(--form-focus-ring);
}
/* Bootstrap-like form-check (AppsTemplate) */
.form-check {
display: flex;
align-items: center;
gap: 0.625rem;
margin: 0;
min-height: 1.5rem;
}
.form-check-label {
font-weight: 500;
font-size: 0.9rem;
color: var(--text);
line-height: 1.5;
cursor: pointer;
user-select: none;
}
.form-check-group {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1rem 1.25rem;
}
/* iOS-style switch */
.form-switch .form-check-input {
width: 2.5em;
height: 1.5em;
min-width: 2.5em;
border-radius: 2em;
border: none;
background-color: var(--form-switch-track-off);
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='%23fff'/%3e%3c/svg%3e");
background-position: left center;
background-size: 1.25em 1.25em;
}
.form-switch .form-check-input:checked {
background-color: var(--orange-500);
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='%23fff'/%3e%3c/svg%3e");
background-position: right center;
}
.form-switch .form-check-input:focus {
box-shadow: var(--form-focus-ring);
}
.form-switch .form-check-label {
padding-top: 0.1em;
}
.schema-field > .form-check.form-switch {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
align-items: center;
gap: 0.35rem 0.75rem;
}
/* Boolean: title + tip on row 1, switch on row 2 — aligned with inputs in the grid cell beside */
.schema-field--boolean > .form-check.form-switch {
width: max-content;
max-width: 100%;
flex-wrap: nowrap;
}
.form-check-group .form-switch {
flex-shrink: 0;
}
/* Field labels: gradient underline grows on focus (AppsTemplate) — только заголовок поля */
.schema-field > label,
.schema-field > .schema-field-label-row > label {
position: relative;
font-size: 0.875rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--muted);
}
.schema-field > label::after,
.schema-field > .schema-field-label-row > label::after {
content: "";
display: block;
width: 30px;
height: 2px;
margin-top: 0.35rem;
border-radius: 2px;
background: linear-gradient(90deg, var(--orange-400), var(--orange-600));
transition: var(--form-transition);
}
.schema-field:focus-within > label::after,
.schema-field:focus-within > .schema-field-label-row > label::after {
width: 56px;
}
.schema-field-label-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
}
.schema-field-tip-wrap {
position: relative;
flex-shrink: 0;
}
.schema-field-tip {
display: inline-flex;
align-items: center;
justify-content: center;
width: 56px;
min-width: 56px;
height: 20px;
min-height: 20px;
padding: 0 6px;
border-radius: 10px;
border: 1px solid var(--input-border);
background: var(--bg-panel);
color: var(--orange-400);
cursor: help;
transition: var(--form-transition);
}
.schema-field-tip svg {
width: 14px;
height: 14px;
display: block;
flex-shrink: 0;
}
.schema-field-tip:hover,
.schema-field-tip:focus-visible {
border-color: var(--orange-500);
background: var(--accent-soft);
color: var(--orange-500);
outline: none;
box-shadow: var(--form-focus-ring);
}
.schema-field-tip-panel {
position: absolute;
right: 0;
top: calc(100% + 8px);
min-width: 220px;
max-width: min(380px, 92vw);
padding: 12px 14px;
font-size: 0.8rem;
font-weight: 500;
line-height: 1.45;
white-space: pre-wrap;
text-align: left;
color: var(--text);
background: var(--card);
border: 1px solid var(--card-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-card);
z-index: 80;
opacity: 0;
visibility: hidden;
pointer-events: none;
transform: translateY(-6px);
transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}
.schema-field-tip-panel--blocks {
white-space: normal;
min-width: 260px;
max-width: min(480px, 96vw);
}
.schema-field-tip-block {
margin: 0;
font-size: 0.8rem;
font-weight: 500;
line-height: 1.5;
white-space: pre-wrap;
text-align: left;
}
.schema-field-tip-block--sep {
margin-top: 0.7rem;
padding-top: 0.7rem;
border-top: 1px solid color-mix(in srgb, var(--card-border) 85%, transparent);
}
body[data-theme="light"] .schema-field-tip-block--sep {
border-top-color: color-mix(in srgb, var(--card-border) 80%, #ccc);
}
.schema-field-tip-wrap:hover .schema-field-tip-panel,
.schema-field-tip-wrap:focus-within .schema-field-tip-panel {
opacity: 1;
visibility: visible;
pointer-events: auto;
transform: translateY(0);
}
.auth-label {
display: block;
margin: 0 0 0.35rem;
font-size: 0.875rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--muted);
}
.auth-label::after {
content: "";
display: block;
width: 30px;
height: 2px;
margin-bottom: 0.5rem;
border-radius: 2px;
background: linear-gradient(90deg, var(--orange-400), var(--orange-600));
transition: var(--form-transition);
}
.auth-field {
margin-bottom: 1.25rem;
}
.auth-field:focus-within .auth-label::after {
width: 56px;
}
.auth-form > .auth-submit {
margin-top: 0.25rem;
margin-bottom: 0;
}
.schema-field input, .schema-field select { width: min(520px, 100%); }
.schema-field textarea {
width: 100%;
resize: vertical;
min-height: 140px;
font-family: var(--font-mono);
line-height: 1.45;
font-size: 0.85rem;
}
.toolbar-row input, .toolbar-row select { min-height: 2.75rem; }
.schema-field {
display: flex;
flex-direction: column;
margin-bottom: 1rem;
gap: 0.5rem;
position: relative;
}
.schema-field-wide { grid-column: 1 / -1; }
.schema-field--hint-only { margin-bottom: 0.5rem; }
.schema-field--hint-only .schema-field-hint-title {
font-weight: 600;
font-size: 0.88rem;
color: var(--text);
}
.field-large { min-height: 220px; }
.schema-grid,
#addon-schema-fields,
#cluster-schema-fields {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
align-items: start;
}
/* Provisioning: all, addons, vault, inventory — одна колонка, поля не «теряются» в сетке */
.schema-grid--provisioning-yaml {
display: flex;
flex-direction: column;
gap: 16px;
align-items: stretch;
}
.schema-grid--provisioning-yaml .schema-field-wide {
width: 100%;
min-width: 0;
}
.h3 { font-size: 0.95rem; font-weight: 800; margin: 0 0 8px; color: var(--text); }
.data-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.data-table th,
.data-table td {
border: 1px solid var(--card-border);
padding: 8px 10px;
text-align: left;
}
.data-table th { background: var(--bg-panel); color: var(--muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; }
.stack-hostvars { display: flex; flex-direction: column; gap: 10px; margin-bottom: 8px; }
.hostvar-row { border: 1px solid var(--card-border); border-radius: 10px; padding: 10px 12px; background: var(--bg-elevated); }
.hostvar-row__head { display: flex; gap: 8px; align-items: center; margin-bottom: 6px; flex-wrap: wrap; }
.hostvar-row__head input[type="text"] { flex: 1; min-width: 120px; }
.table-wrap { border-radius: var(--radius-md); border: 1px solid var(--card-border); overflow: hidden; }
.form-modern {
display: block;
margin-bottom: 10px;
padding: 18px;
border: 1px solid var(--card-border);
border-radius: var(--radius-lg);
background: var(--bg-elevated);
}
.addon-chooser {
margin-bottom: 16px;
padding: 16px;
border: 1px solid var(--card-border);
border-radius: var(--radius-lg);
background: var(--bg-panel);
}
.addon-chooser .schema-field { margin-bottom: 0; min-width: 260px; flex: 1 1 260px; }
.addon-chooser .schema-field select { width: 100%; }
.addon-config-form {
display: block;
margin-bottom: 10px;
padding: 18px;
border: 1px solid var(--card-border);
border-radius: var(--radius-lg);
background: var(--bg-elevated);
}
.form-actions {
margin-top: 16px;
display: flex;
justify-content: flex-end;
gap: 10px;
padding-top: 14px;
border-top: 1px solid var(--border);
}
.form-actions button { min-width: 150px; }
.form-actions-start { justify-content: flex-start; }
.toolbar-form {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
align-items: end;
}
.toolbar-form > input,
.toolbar-form > select {
width: 100%;
min-width: 0;
}
.toolbar-form > button,
.toolbar-form > .checkline,
.toolbar-form > .form-check,
.toolbar-form > .form-actions {
grid-column: 1 / -1;
}
.toolbar-form > .checkline,
.toolbar-form > .form-check {
margin-top: 2px;
background: var(--bg-panel);
border: 2px solid var(--border);
border-radius: var(--radius-md);
padding: 12px 14px;
}
.toolbar-form > .form-check.form-switch {
background: transparent;
border: none;
padding: 4px 0;
}
.hidden { display: none; }
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.roles-form-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.roles-form-grid .schema-field--wide {
grid-column: 1 / -1;
}
.roles-page #role-view-description {
font-family: inherit;
min-height: 7.5rem;
}
.roles-form-actions {
grid-column: 1 / -1;
display: flex;
justify-content: flex-start;
}
.roles-page-bottom-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px;
margin-top: 4px;
padding: 18px 0 8px;
border-top: 1px solid var(--card-border);
}
/* Role view/create: one dashboard card; tabs span full width (segment strip, not pill buttons). */
.roles-page .role-view-tabbed-shell {
padding: 0;
overflow: hidden;
}
.roles-page .role-view-tabbed-shell.dashboard-panel--primary {
padding-bottom: 0;
}
.roles-page .role-view-tabs {
display: flex;
width: 100%;
margin: 0;
padding: 0;
border: none;
border-radius: 0;
background: color-mix(in srgb, var(--bg-panel) 55%, var(--card));
border-bottom: 1px solid var(--card-border);
}
.roles-page .role-view-tab {
flex: 1 1 0;
min-width: 0;
appearance: none;
margin: 0;
padding: 14px 12px 13px;
text-align: center;
cursor: pointer;
border: none;
border-radius: 0;
border-bottom: 3px solid transparent;
margin-bottom: -1px;
font-size: 0.94rem;
font-weight: 600;
font-family: inherit;
letter-spacing: -0.015em;
line-height: 1.25;
color: var(--muted);
background: transparent;
box-shadow: none;
transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.roles-page .role-view-tab + .role-view-tab {
box-shadow: -1px 0 0 var(--card-border);
}
.roles-page .role-view-tab:hover {
color: var(--text);
background: color-mix(in srgb, var(--card) 72%, transparent);
}
.roles-page .role-view-tab:focus-visible {
outline: none;
position: relative;
z-index: 1;
box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 50%, transparent);
}
.roles-page .role-view-tab[aria-selected="true"] {
color: var(--text);
background: var(--card);
border-bottom-color: var(--accent);
}
.roles-page .role-view-tabbed-panels {
padding: 22px 24px 24px;
}
.roles-page .role-view-tabbed-shell.dashboard-panel--primary .role-view-tabbed-panels {
padding-bottom: 18px;
}
.roles-page .role-view-tab-panel[hidden] {
display: none !important;
}
.roles-catalog {
display: grid;
gap: 14px;
}
.roles-category-block {
border: 1px solid var(--card-border);
border-radius: var(--radius-md);
padding: 12px;
background: color-mix(in srgb, var(--card) 90%, var(--bg-panel));
}
.roles-category-block h3 {
margin: 0 0 10px;
}
.roles-role-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 9px 10px;
border-radius: 8px;
}
.roles-role-row:nth-child(even) {
background: color-mix(in srgb, var(--bg-panel) 86%, transparent);
}
.roles-role-row__main {
display: flex;
flex-direction: column;
gap: 2px;
}
.roles-role-row__export {
padding: 6px 10px;
font-size: 0.8rem;
}
.roles-category-modal {
width: min(92vw, 560px);
}
.roles-category-modal__new {
display: flex;
gap: 8px;
margin-bottom: 12px;
}
.roles-category-modal__new input {
flex: 1;
min-width: 0;
}
.roles-category-modal__list {
max-height: 320px;
overflow: auto;
display: grid;
gap: 8px;
}
.admin-categories__toolbar {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 14px;
flex-wrap: wrap;
}
.admin-categories__name-input {
flex: 1;
min-width: min(100%, 220px);
box-sizing: border-box;
padding: 10px 12px;
border-radius: var(--radius-sm);
border: 1px solid var(--input-border);
background: color-mix(in srgb, var(--bg-panel) 94%, var(--card));
color: var(--text);
font: inherit;
font-size: 0.95rem;
}
.admin-categories__list {
display: grid;
gap: 8px;
max-height: none;
overflow: visible;
}
.roles-category-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
border: 1px solid var(--card-border);
border-radius: var(--radius-sm);
padding: 8px 10px;
}
.roles-category-row__main {
display: flex;
align-items: center;
gap: 10px;
flex: 1;
min-width: 0;
}
.roles-category-row__main .admin-categories__name-input {
flex: 1;
min-width: 0;
}
.admin-lint-toolbar {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
flex-shrink: 0;
}
.admin-lint-toolbar--footer {
margin-top: 20px;
padding-top: 18px;
border-top: 1px solid var(--card-border);
justify-content: flex-end;
}
.admin-lint-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
gap: 14px;
}
.admin-lint-card {
border: 1px solid var(--card-border);
border-radius: var(--radius-md);
padding: 14px 16px;
background: color-mix(in srgb, var(--bg-panel) 92%, transparent);
}
.admin-lint-card__title {
margin: 0 0 6px;
font-size: 1rem;
font-weight: 700;
letter-spacing: -0.02em;
}
.admin-lint-card__hint {
margin: 0 0 14px;
font-size: 0.82rem;
line-height: 1.45;
}
.admin-lint-card__controls {
display: flex;
flex-direction: column;
gap: 12px;
}
.admin-lint-card__row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.admin-lint-card__label {
font-size: 0.88rem;
color: var(--muted);
}
.admin-lint-card__field {
margin: 0;
}
.admin-lint-card__field input[type="number"] {
max-width: 8rem;
}
.admin-category-role-badge {
flex-shrink: 0;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 2rem;
padding: 4px 11px;
border-radius: 999px;
font-size: 0.78rem;
font-weight: 700;
font-variant-numeric: tabular-nums;
letter-spacing: 0.02em;
border: 1px solid var(--card-border);
color: var(--text);
background: color-mix(in srgb, var(--bg-panel) 88%, var(--card));
}
.admin-category-role-badge--has-roles {
border-color: rgba(74, 222, 128, 0.42);
color: #86efac;
background: rgba(34, 197, 94, 0.16);
}
body[data-theme="light"] .admin-category-role-badge--has-roles {
border-color: rgba(22, 163, 74, 0.4);
color: #15803d;
background: rgba(34, 197, 94, 0.14);
}
.roles-category-row__meta {
display: flex;
flex-direction: column;
gap: 2px;
}
.roles-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 14px;
}
.roles-list-item {
position: relative;
border: 1px solid var(--card-border);
border-radius: var(--radius-lg);
padding: 14px 14px 12px;
background:
linear-gradient(135deg, color-mix(in srgb, var(--card) 92%, #22140a) 0%, var(--card) 100%),
linear-gradient(165deg, rgba(249, 115, 22, 0.08) 0%, transparent 60%);
box-shadow: var(--shadow-card);
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.roles-list-item__card-link {
position: absolute;
inset: 0;
z-index: 1;
border-radius: inherit;
text-decoration: none;
}
.roles-list-item__card-link:focus-visible {
outline: 2px solid color-mix(in srgb, var(--orange-400) 70%, transparent);
outline-offset: 2px;
}
.roles-list-item__body {
position: relative;
z-index: 2;
pointer-events: none;
}
.roles-list-item:hover {
transform: translateY(-2px);
border-color: color-mix(in srgb, var(--orange-500) 35%, var(--card-border));
box-shadow: 0 16px 36px rgba(0, 0, 0, 0.24);
}
.roles-list-item__head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.roles-list-item__badges {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
gap: 8px;
}
.roles-list-item__head h3 {
margin: 0;
font-size: 1rem;
display: flex;
align-items: center;
gap: 8px;
}
.roles-list-item__category {
border: 1px solid var(--accent-border);
border-radius: 999px;
padding: 2px 8px;
font-size: 0.75rem;
color: var(--orange-200);
}
.roles-list-item__visibility {
flex-shrink: 0;
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 0.68rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 4px 10px;
border-radius: 999px;
border: 1px solid var(--input-border);
color: var(--muted);
}
.roles-list-item__visibility i {
font-size: 0.72rem;
opacity: 0.92;
}
.roles-list-item__visibility.roles-vis--public {
border-color: color-mix(in srgb, var(--orange-400) 45%, var(--border));
color: var(--orange-200);
}
.roles-list-item__visibility.roles-vis--personal {
color: var(--muted);
}
.roles-list-item__visibility.roles-vis--team {
border-color: color-mix(in srgb, #60a5fa 50%, var(--border));
color: #93c5fd;
}
.roles-list-item__description {
margin: 8px 0 6px;
}
.roles-list-item__chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin: 2px 0 10px;
}
.roles-list-item__chips--compact {
margin: 0;
max-width: 22rem;
}
.role-chip {
display: inline-flex;
align-items: center;
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.02em;
padding: 3px 9px;
border-radius: 999px;
border: 1px solid var(--border);
line-height: 1.25;
}
.role-chip--tag {
background: color-mix(in srgb, var(--accent, #6366f1) 14%, transparent);
color: var(--text, #e8e8ef);
}
.role-chip--os {
border-width: 1px;
}
.role-chip--os-universal {
background: color-mix(in srgb, #a78bfa 22%, transparent);
border-color: color-mix(in srgb, #a78bfa 42%, var(--border));
color: #ddd6fe;
}
.role-chip--os-rhel {
background: color-mix(in srgb, #f97316 18%, transparent);
border-color: color-mix(in srgb, #f97316 45%, var(--border));
color: #fed7aa;
}
.role-chip--os-debian {
background: color-mix(in srgb, #e11d48 16%, transparent);
border-color: color-mix(in srgb, #e11d48 38%, var(--border));
color: #fecdd3;
}
.role-chip--os-alpine {
background: color-mix(in srgb, #0ea5e9 18%, transparent);
border-color: color-mix(in srgb, #0ea5e9 42%, var(--border));
color: #bae6fd;
}
.role-chip--os-suse {
background: color-mix(in srgb, #84cc16 16%, transparent);
border-color: color-mix(in srgb, #84cc16 40%, var(--border));
color: #d9f99d;
}
.role-chip--os-arch {
background: color-mix(in srgb, #14b8a6 18%, transparent);
border-color: color-mix(in srgb, #14b8a6 40%, var(--border));
color: #99f6e4;
}
.role-chip--os-bsd {
background: color-mix(in srgb, #eab308 14%, transparent);
border-color: color-mix(in srgb, #eab308 38%, var(--border));
color: #fef08a;
}
.role-chip--os-windows {
background: color-mix(in srgb, #38bdf8 16%, transparent);
border-color: color-mix(in srgb, #38bdf8 40%, var(--border));
color: #e0f2fe;
}
/* Target OS families: two-column grid + switch toggles (role form) */
.role-os-family-grid {
display: flex;
flex-direction: column;
gap: 0;
}
.role-os-family-grid--toggles {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0;
border: 1px solid var(--card-border);
border-radius: var(--radius-md);
overflow: hidden;
background: color-mix(in srgb, var(--card) 88%, var(--bg-panel));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.role-os-family-grid--toggles .role-os-family-row {
border-bottom: 1px solid color-mix(in srgb, var(--card-border) 70%, transparent);
border-right: none;
}
.role-os-family-grid--toggles .role-os-family-row:nth-child(odd) {
border-right: 1px solid color-mix(in srgb, var(--card-border) 70%, transparent);
}
.role-os-family-grid--toggles .role-os-family-row:nth-last-child(-n + 2) {
border-bottom: none;
}
@media (max-width: 540px) {
.role-os-family-grid--toggles {
grid-template-columns: 1fr;
}
.role-os-family-grid--toggles .role-os-family-row:nth-child(odd) {
border-right: none;
}
.role-os-family-grid--toggles .role-os-family-row:nth-last-child(-n + 2) {
border-bottom: 1px solid color-mix(in srgb, var(--card-border) 70%, transparent);
}
.role-os-family-grid--toggles .role-os-family-row:last-child {
border-bottom: none;
}
}
.role-os-family-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
margin: 0;
padding: 12px 14px;
cursor: pointer;
border-bottom: 1px solid color-mix(in srgb, var(--card-border) 70%, transparent);
background: transparent;
transition: background 0.15s ease, box-shadow 0.15s ease;
-webkit-tap-highlight-color: transparent;
}
.role-os-family-row--compact {
padding-block: 10px;
}
.role-os-family-grid:not(.role-os-family-grid--toggles) .role-os-family-row:last-child {
border-bottom: 0;
}
.role-os-family-row:hover {
background: color-mix(in srgb, var(--accent, #f97316) 6%, transparent);
}
.role-os-family-row:has(.role-os-switch__input:focus-visible) {
background: color-mix(in srgb, var(--accent, #f97316) 8%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}
.role-os-family-row:has(.role-os-switch__input:checked) {
background: color-mix(in srgb, var(--accent, #f97316) 4%, transparent);
}
.role-os-family-row:has(.role-os-switch__input:disabled) {
cursor: not-allowed;
opacity: 0.55;
}
.role-os-family-row__copy {
display: block;
min-width: 0;
flex: 1;
}
.role-os-family-row__title {
display: block;
font-weight: 600;
font-size: 0.9rem;
line-height: 1.3;
letter-spacing: -0.01em;
color: var(--text);
}
.role-os-family-row__hint {
display: block;
font-size: 0.75rem;
line-height: 1.4;
margin-top: 3px;
color: var(--muted);
}
/* iOS-style switch */
.role-os-switch {
position: relative;
flex-shrink: 0;
width: 48px;
height: 28px;
}
.role-os-switch__input {
position: absolute;
inset: 0;
z-index: 2;
width: 100%;
height: 100%;
margin: 0;
opacity: 0;
cursor: pointer;
}
.role-os-switch__input:disabled {
cursor: not-allowed;
}
.role-os-switch__track {
display: block;
position: relative;
width: 48px;
height: 28px;
border-radius: 999px;
background: color-mix(in srgb, var(--muted) 35%, var(--card));
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25);
transition: background 0.2s ease, box-shadow 0.2s ease;
pointer-events: none;
}
.role-os-switch__thumb {
position: absolute;
top: 3px;
left: 3px;
width: 22px;
height: 22px;
border-radius: 50%;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}
.role-os-switch__input:checked + .role-os-switch__track {
background: linear-gradient(
135deg,
color-mix(in srgb, var(--accent, #f97316) 92%, #ea580c),
color-mix(in srgb, var(--accent, #f97316) 75%, #c2410c)
);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.06);
}
.role-os-switch__input:checked + .role-os-switch__track .role-os-switch__thumb {
transform: translateX(20px);
}
.role-os-switch__input:focus-visible + .role-os-switch__track {
outline: 2px solid color-mix(in srgb, var(--accent, #f97316) 65%, transparent);
outline-offset: 3px;
}
.role-os-switch__input:disabled + .role-os-switch__track {
opacity: 0.55;
}
body[data-theme="light"] .role-os-family-grid--toggles {
background: var(--card);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 1px 2px rgba(15, 23, 42, 0.06);
}
body[data-theme="light"] .role-os-family-row {
border-bottom-color: color-mix(in srgb, var(--card-border) 85%, transparent);
}
body[data-theme="light"] .role-os-family-row:hover {
background: color-mix(in srgb, var(--accent, #f97316) 5%, #fff);
}
body[data-theme="light"] .role-os-switch__track {
background: color-mix(in srgb, #64748b 28%, #e2e8f0);
}
/* Role form: team picker — only visible when visibility = Team (JS toggles [hidden]) */
#role-team-picker-wrap[hidden] {
display: none !important;
}
.role-team-picker-field:not([hidden]) {
margin-top: 6px;
padding: 14px 16px;
border-radius: var(--radius-md);
border: 1px solid color-mix(in srgb, var(--card-border) 88%, var(--accent, #f97316));
background: color-mix(in srgb, var(--card) 94%, var(--bg-panel));
}
.role-team-picker-actions {
display: flex;
align-items: center;
gap: 14px;
flex-wrap: wrap;
}
.role-team-display--summary {
flex: 1;
min-width: 12rem;
font-weight: 500;
line-height: 1.35;
}
.role-team-picker-open-btn {
flex-shrink: 0;
}
.role-team-display {
font-weight: 500;
}
.role-team-picker-list {
list-style: none;
margin: 10px 0 0;
padding: 0;
max-height: min(50vh, 320px);
overflow-y: auto;
}
.role-team-picker-list li {
margin: 0 0 8px;
}
.role-team-picker-item {
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px;
text-align: left;
padding: 10px 12px;
border-radius: var(--radius-md);
border: 1px solid var(--card-border);
background: var(--card);
cursor: pointer;
font: inherit;
color: var(--text);
transition: border-color 0.15s ease, background 0.15s ease;
}
.role-team-picker-item:hover {
border-color: color-mix(in srgb, var(--accent) 55%, var(--card-border));
}
.role-team-picker-item__name {
font-weight: 600;
font-size: 0.9rem;
}
.role-team-picker-item__desc {
font-size: 0.78rem;
line-height: 1.35;
display: block;
}
.roles-list-item__meta {
font-size: 0.82rem;
}
.roles-list-item__meta-row {
margin-top: 8px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.roles-list-item__actions {
display: flex;
gap: 8px;
align-items: center;
}
.roles-list-item__actions-card {
position: relative;
z-index: 3;
pointer-events: auto;
border: 1px solid color-mix(in srgb, var(--card-border) 80%, var(--orange-500));
border-radius: var(--radius-sm);
padding: 6px;
background: color-mix(in srgb, var(--card) 90%, var(--bg-panel));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.roles-pagination {
margin-top: 14px;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10px;
}
.roles-toolbar {
display: flex;
align-items: flex-end;
gap: 12px;
margin: 0 0 12px;
}
.roles-toolbar--top {
justify-content: space-between;
align-items: flex-end;
flex-wrap: wrap;
}
.roles-toolbar-filters-right {
display: flex;
gap: 12px;
align-items: flex-end;
margin-left: auto;
flex-wrap: wrap;
}
.roles-toolbar--bottom {
justify-content: space-between;
align-items: center;
margin-top: 14px;
margin-bottom: 0;
}
.roles-filter-card {
border: 1px solid var(--card-border);
border-radius: var(--radius-md);
padding: 10px 12px;
background: color-mix(in srgb, var(--card) 90%, var(--bg-panel));
box-shadow: var(--shadow-card);
}
.roles-filter-card--search {
flex: 1;
min-width: 240px;
}
.roles-filter-card--category {
width: 240px;
}
.roles-filter-card--visibility {
width: 200px;
}
.roles-filter-card--page-size {
width: auto;
border: 0;
background: transparent;
box-shadow: none;
padding: 0;
}
.roles-filter-card label {
display: flex;
flex-direction: column;
gap: 6px;
font-size: 0.8rem;
color: var(--muted);
}
.roles-filter-card select,
.roles-filter-card input {
width: 100%;
}
@media (max-width: 900px) {
.roles-toolbar--top,
.roles-toolbar--bottom {
flex-direction: column;
align-items: stretch;
}
.roles-toolbar-filters-right {
margin-left: 0;
width: 100%;
}
.roles-filter-card--category,
.roles-filter-card--visibility,
.roles-filter-card--page-size {
width: 100%;
flex: 1 1 auto;
min-width: 0;
}
.roles-pagination {
width: 100%;
justify-content: space-between;
}
}
.role-file-catalog-toolbar {
display: inline-flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
}
.roles-page .role-file-catalog-toolbar .btn-icon:hover {
filter: none;
box-shadow: none;
}
.roles-page .role-file-catalog-toolbar .btn-icon:focus-visible {
outline: none;
filter: none;
box-shadow: 0 0 0 2px color-mix(in srgb, var(--border) 78%, var(--text));
}
.roles-page .role-file-catalog-toolbar .btn-icon:focus {
outline: none;
filter: none;
box-shadow: none;
}
.role-file-catalog {
border: 1px solid var(--card-border);
border-radius: var(--radius-md);
padding: 12px 14px;
background: color-mix(in srgb, var(--card) 88%, var(--bg-panel));
font-size: 0.88rem;
}
.role-file-catalog__hint-icons {
display: inline-flex;
gap: 6px;
vertical-align: middle;
color: var(--muted);
}
.role-file-catalog__node {
--catalog-depth: 0;
}
.role-file-catalog__dir {
margin-bottom: 2px;
}
.role-file-catalog__dir-body {
margin-top: 0;
padding-left: 4px;
}
.role-file-catalog__dir-nest {
margin-bottom: 2px;
}
.role-file-catalog__row {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 8px;
padding: 5px 8px 5px calc(var(--catalog-depth) * 14px + 6px);
margin: 0 -4px;
border-radius: var(--radius-sm);
transition: background 0.12s ease;
}
.role-file-catalog__row:hover {
background: color-mix(in srgb, var(--bg-panel) 55%, transparent);
}
.role-file-catalog__file-line,
.role-file-catalog__dir-line {
display: flex;
align-items: center;
gap: 6px;
min-width: 0;
width: 100%;
}
.role-file-catalog__row--dir .role-file-catalog__dir-label {
display: inline-flex;
align-items: center;
gap: 8px;
flex: 0 1 auto;
min-width: 0;
max-width: calc(100% - 108px);
color: var(--muted);
font-weight: 500;
font-size: 0.84rem;
}
.role-file-catalog__row--dir .fa-folder {
flex-shrink: 0;
opacity: 0.85;
font-size: 0.82rem;
}
.role-file-catalog__file-main {
flex: 0 1 auto;
min-width: 0;
max-width: calc(100% - 108px);
display: inline-flex;
align-items: center;
gap: 8px;
margin: 0;
padding: 0;
border: none;
border-radius: 4px;
background: transparent;
color: color-mix(in srgb, var(--text) 88%, var(--muted));
font: inherit;
font-size: 0.85rem;
font-weight: 400;
text-align: left;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
min-height: 0;
box-shadow: none;
filter: none;
}
.role-file-catalog__file-main:hover {
color: var(--text);
}
.role-file-catalog__file-main:hover,
.role-file-catalog__file-main:focus,
.role-file-catalog__file-main:focus-visible,
.role-file-catalog__file-main:active {
outline: none !important;
box-shadow: none !important;
filter: none !important;
}
.role-file-catalog__file-static {
flex: 0 1 auto;
min-width: 0;
max-width: calc(100% - 48px);
display: inline-flex;
align-items: center;
gap: 8px;
color: var(--muted);
font-size: 0.85rem;
}
.role-file-catalog__row--upload .role-file-catalog__file-static {
max-width: calc(100% - 78px);
}
.role-file-catalog__file-static .fa-paperclip {
flex-shrink: 0;
opacity: 0.65;
font-size: 0.78rem;
}
.role-file-catalog__upload-badge {
flex-shrink: 0;
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 2px 6px;
border-radius: 4px;
border: 1px solid var(--card-border);
color: var(--muted);
background: color-mix(in srgb, var(--bg-panel) 90%, var(--card));
}
.role-file-catalog .role-file-catalog__inline-action:focus-visible {
outline: none;
box-shadow: 0 0 0 2px color-mix(in srgb, var(--border) 78%, var(--text));
}
.role-file-catalog__file-main .fa-file-lines {
flex-shrink: 0;
font-size: 0.78rem;
opacity: 0.55;
color: var(--muted);
}
.role-file-catalog__name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.role-file-catalog__inline-action {
flex-shrink: 0;
opacity: 0;
transition: opacity 0.12s ease;
}
.role-file-catalog .role-file-catalog__inline-action:hover {
filter: none;
box-shadow: none;
}
.role-file-catalog__row:hover .role-file-catalog__inline-action {
opacity: 1;
}
@media (hover: none) {
.role-file-catalog__inline-action {
opacity: 1;
}
}
.app-modal-overlay.app-modal-overlay--fill .app-modal--role-file {
width: calc(100vw - 24px);
max-width: calc(100vw - 24px);
height: calc(100vh - 24px);
max-height: calc(100vh - 24px);
box-sizing: border-box;
}
.app-modal--role-file {
display: flex;
flex-direction: column;
min-height: 0;
}
.app-modal-overlay.app-modal-overlay--fill .app-modal--role-test {
width: min(96vw, 920px);
max-width: calc(100vw - 24px);
height: min(88vh, 860px);
max-height: calc(100vh - 24px);
display: flex;
flex-direction: column;
min-height: 0;
box-sizing: border-box;
}
.app-modal--role-test .app-modal__title {
flex-shrink: 0;
}
.role-test-modal__meta {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
flex-shrink: 0;
margin-bottom: 8px;
}
.role-test-modal__hint {
margin: 0;
}
.role-test-modal__log-outer {
position: relative;
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.role-test-modal__awaiting {
position: absolute;
inset: 0;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 18px;
padding: 24px;
text-align: center;
border-radius: var(--radius-md);
background: color-mix(in srgb, #0a0c10 88%, transparent);
border: 1px solid color-mix(in srgb, var(--border) 72%, #1e293b);
box-sizing: border-box;
transition:
opacity 0.25s ease,
visibility 0.25s ease;
}
.role-test-modal__awaiting--done {
opacity: 0;
visibility: hidden;
pointer-events: none;
}
.role-test-modal__awaiting-spinner {
width: 40px;
height: 40px;
border-radius: 50%;
border: 3px solid color-mix(in srgb, #94a3b8 35%, transparent);
border-top-color: #38bdf8;
animation: role-test-await-spin 0.85s linear infinite;
box-sizing: border-box;
}
@keyframes role-test-await-spin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.role-test-modal__awaiting-spinner {
animation: none;
border-top-color: #38bdf8;
opacity: 0.92;
}
body[data-theme="light"] .role-test-modal__awaiting-spinner {
border-top-color: #0284c7;
}
}
.role-test-modal__awaiting-text {
font-size: 0.84rem;
line-height: 1.45;
color: #cbd5e1;
max-width: 26rem;
}
body[data-theme="light"] .role-test-modal__awaiting {
background: color-mix(in srgb, #f1f5f9 92%, #ffffff);
border-color: var(--input-border);
}
body[data-theme="light"] .role-test-modal__awaiting-text {
color: #475569;
}
body[data-theme="light"] .role-test-modal__awaiting-spinner {
border-color: color-mix(in srgb, #64748b 35%, transparent);
border-top-color: #0284c7;
}
.role-test-modal__log {
flex: 1;
min-height: 220px;
overflow: auto;
font-family: var(--font-mono);
font-size: 0.78rem;
line-height: 1.45;
padding: 12px 14px;
border-radius: var(--radius-md);
background: #0a0c10;
color: #e8ecf4;
border: 1px solid color-mix(in srgb, var(--border) 72%, #1e293b);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.role-test-modal__line {
white-space: pre-wrap;
word-break: break-word;
}
.role-test-modal__line--sys {
color: #94a3b8;
font-style: italic;
margin-bottom: 4px;
}
body[data-theme="light"] .role-test-modal__log {
background: #f1f5f9;
color: #0f172a;
border-color: var(--input-border);
}
body[data-theme="light"] .role-test-modal__line--sys {
color: #64748b;
}
.status-queued {
background: rgba(148, 163, 184, 0.14);
border-color: rgba(148, 163, 184, 0.38);
color: #cbd5e1;
}
.app-modal--role-file .app-modal__title {
flex-shrink: 0;
font-family: var(--font-mono);
font-size: 0.88rem;
font-weight: 600;
word-break: break-all;
line-height: 1.35;
}
.app-modal--role-file .role-file-edit-modal__path-wrap {
flex-shrink: 0;
margin-top: 10px;
}
.app-modal--role-file .role-file-edit-modal__path {
width: 100%;
box-sizing: border-box;
margin-top: 6px;
padding: 10px 12px;
border-radius: var(--radius-sm);
border: 1px solid var(--input-border);
background: color-mix(in srgb, var(--bg-panel) 94%, var(--card));
color: var(--text);
font-family: var(--font-mono);
font-size: 0.82rem;
}
.app-modal--role-file select.role-file-edit-modal__path {
min-height: 2.5rem;
cursor: pointer;
}
.role-file-edit-modal__editor-wrap {
flex: 1 1 auto;
min-height: 0;
margin-top: 12px;
display: flex;
flex-direction: column;
border-radius: var(--radius-sm);
border: 1px solid var(--input-border);
overflow: hidden;
background: color-mix(in srgb, var(--bg-panel) 94%, var(--card));
}
.role-file-edit-modal__editor-wrap .CodeMirror {
flex: 1 1 auto;
min-height: min(70vh, calc(100vh - 220px));
height: auto;
font-family: var(--font-mono);
font-size: 0.82rem;
line-height: 1.45;
}
.role-file-edit-modal__editor-wrap .CodeMirror .CodeMirror-gutters {
pointer-events: auto;
}
.role-file-edit-modal__editor-wrap .CodeMirror .CodeMirror-gutter.roleforge-lint {
width: 22px;
min-width: 22px;
pointer-events: auto;
}
.role-file-cm-lint-marker {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 11px;
height: 11px;
margin: 3px auto 0;
border-radius: 50%;
cursor: help;
box-sizing: border-box;
vertical-align: middle;
pointer-events: auto;
}
/* Invisible larger hover target so the native title tooltip is easy to trigger. */
.role-file-cm-lint-marker::after {
content: "";
position: absolute;
inset: -10px;
}
.role-file-cm-lint-marker--error {
background: #ef4444;
box-shadow: 0 0 0 1px color-mix(in srgb, #ef4444 65%, #000);
}
.role-file-cm-lint-marker--warn {
background: #f59e0b;
box-shadow: 0 0 0 1px color-mix(in srgb, #f59e0b 65%, #000);
}
/* Floating lint tooltip (portal to body; avoids editor overflow clipping). */
.role-file-cm-lint-tooltip-root {
position: fixed;
z-index: 25000;
max-width: min(360px, calc(100vw - 24px));
pointer-events: none;
}
.role-file-cm-lint-tooltip {
padding: 11px 13px;
border-radius: var(--radius-sm);
border: 1px solid var(--card-border);
background: var(--bg-elevated);
color: var(--text);
box-shadow: var(--shadow-card);
font-size: 0.8125rem;
line-height: 1.45;
}
.role-file-cm-lint-tooltip__title {
margin: 0 0 8px;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--muted);
}
.role-file-cm-lint-tooltip__list {
margin: 0;
padding: 0;
list-style: none;
}
.role-file-cm-lint-tooltip__item + .role-file-cm-lint-tooltip__item {
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid var(--border);
}
.role-file-cm-lint-tooltip__head {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px 8px;
}
.role-file-cm-lint-tooltip__pill {
display: inline-block;
margin-right: 8px;
padding: 2px 8px;
border-radius: 999px;
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.03em;
text-transform: uppercase;
vertical-align: baseline;
}
.role-file-cm-lint-tooltip__pill--error {
background: rgba(239, 68, 68, 0.18);
border: 1px solid rgba(248, 113, 113, 0.45);
color: #fca5a5;
}
.role-file-cm-lint-tooltip__pill--warn {
background: rgba(245, 158, 11, 0.18);
border: 1px solid rgba(251, 191, 36, 0.45);
color: #fcd34d;
}
.role-file-cm-lint-tooltip__pill--info {
background: rgba(148, 163, 184, 0.14);
border: 1px solid rgba(148, 163, 184, 0.35);
color: #cbd5e1;
}
.role-file-cm-lint-tooltip__meta {
font-size: 0.72rem;
color: var(--muted);
}
.role-file-cm-lint-tooltip__text {
margin: 6px 0 0;
padding: 0;
font-family: var(--font-sans);
font-size: 0.84rem;
line-height: 1.45;
color: var(--text);
word-break: break-word;
}
body[data-theme="light"] .role-file-cm-lint-tooltip__pill--error {
color: #991b1b;
}
body[data-theme="light"] .role-file-cm-lint-tooltip__pill--warn {
color: #b45309;
}
body[data-theme="light"] .role-file-cm-lint-tooltip__pill--info {
color: #475569;
}
.role-file-edit-modal__editor-wrap .CodeMirror .role-file-cm-lint-line--error {
background: rgba(239, 68, 68, 0.1);
}
.role-file-edit-modal__editor-wrap .CodeMirror .role-file-cm-lint-line--warn {
background: rgba(245, 158, 11, 0.09);
}
body[data-theme="light"] .role-file-edit-modal__editor-wrap .CodeMirror .role-file-cm-lint-line--error {
background: rgba(239, 68, 68, 0.12);
}
body[data-theme="light"] .role-file-edit-modal__editor-wrap .CodeMirror .role-file-cm-lint-line--warn {
background: rgba(245, 158, 11, 0.1);
}
.app-modal--role-file[data-theme-cm="light"] .role-file-edit-modal__editor-wrap .CodeMirror {
background: #fafafa;
color: #383838;
}
.role-file-edit-modal__textarea {
width: 100%;
box-sizing: border-box;
flex: 1 1 auto;
min-height: 12rem;
margin-top: 12px;
padding: 12px 14px;
border-radius: var(--radius-sm);
border: 1px solid var(--input-border);
background: color-mix(in srgb, var(--bg-panel) 94%, var(--card));
color: var(--text);
font-family: var(--font-mono);
font-size: 0.82rem;
line-height: 1.45;
resize: vertical;
}
/* Fallback when CodeMirror is absent: textarea fills modal body */
.role-file-edit-modal__editor-wrap .role-file-edit-modal__textarea {
margin-top: 0;
min-height: min(70vh, calc(100vh - 220px));
flex: 1 1 auto;
}
.app-modal--role-file .app-modal__actions {
flex-shrink: 0;
margin-top: 14px;
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
justify-content: flex-end;
}
.role-file-edit-modal__lint {
flex-shrink: 0;
margin-top: 10px;
max-height: 11rem;
overflow: auto;
padding: 10px 12px;
border-radius: var(--radius-sm);
border: 1px solid var(--card-border);
background: color-mix(in srgb, var(--bg-panel) 92%, var(--card));
font-size: 0.8rem;
line-height: 1.45;
}
.role-file-edit-modal__lint-summary {
margin: 0 0 8px;
font-weight: 600;
}
.role-file-edit-modal__lint-summary--ok {
color: var(--text);
}
.role-file-edit-modal__lint-summary--warn {
color: color-mix(in srgb, var(--text) 75%, #eab308);
}
.role-file-edit-modal__lint-summary--bad {
color: color-mix(in srgb, var(--text) 70%, #f87171);
}
.role-file-edit-modal__lint-list {
margin: 0;
padding-left: 1.1rem;
}
.role-file-edit-modal__lint-list li {
margin-bottom: 6px;
}
.role-file-edit-modal__lint-pos {
font-family: var(--font-mono);
color: var(--muted);
margin-right: 6px;
}
.role-file-edit-modal__lint-level {
text-transform: lowercase;
font-weight: 600;
margin-right: 6px;
color: var(--muted);
}
.role-file-edit-modal__lint-msg {
color: var(--text);
}
.app-modal--files-upload .app-modal__title {
font-family: inherit;
font-size: 1.05rem;
}
.role-files-upload-modal__drop {
border: 2px dashed var(--card-border);
border-radius: var(--radius-md);
padding: 26px 16px;
text-align: center;
color: var(--muted);
background: color-mix(in srgb, var(--bg-panel) 90%, var(--card));
transition:
border-color 0.15s ease,
background 0.15s ease,
color 0.15s ease;
cursor: pointer;
}
.role-files-upload-modal__drop:hover {
border-color: color-mix(in srgb, var(--card-border) 55%, var(--text));
color: var(--text);
}
.role-files-upload-modal__drop.is-dragover {
border-color: color-mix(in srgb, var(--orange-400) 75%, var(--card-border));
background: color-mix(in srgb, var(--orange-500) 07%, var(--bg-panel));
color: var(--text);
}
.role-files-upload-modal__drop:focus-visible {
outline: none;
box-shadow: 0 0 0 2px color-mix(in srgb, var(--border) 78%, var(--text));
}
.role-files-upload-modal__browse {
margin-top: 10px;
display: flex;
justify-content: center;
}
.role-files-upload-modal__list-wrap {
margin-top: 14px;
max-height: 200px;
overflow: auto;
border: 1px solid var(--card-border);
border-radius: var(--radius-sm);
padding: 8px 10px;
background: color-mix(in srgb, var(--card) 92%, var(--bg-panel));
}
.role-files-upload-modal__list {
margin: 0;
padding: 0;
list-style: none;
display: grid;
gap: 6px;
}
.role-files-upload-modal__item {
display: flex;
align-items: center;
gap: 10px;
font-size: 0.84rem;
flex-wrap: wrap;
}
.role-files-upload-modal__item span:first-of-type {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: var(--font-mono);
}
.role-files-upload-modal__remove {
padding: 4px 10px;
font-size: 0.78rem;
}
.role-files-editor {
display: grid;
gap: 8px;
margin-bottom: 8px;
}
.role-file-row {
border: 1px solid var(--card-border);
border-radius: var(--radius-sm);
padding: 8px;
display: grid;
gap: 8px;
background: color-mix(in srgb, var(--card) 88%, var(--bg-panel));
}
.role-file-row .role-file-path {
font-family: var(--font-mono);
}
.cluster-summary-card { margin-top: 8px; }
.summary-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 14px;
margin-top: 12px;
}
.summary-item {
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: 14px 16px;
display: flex;
flex-direction: column;
gap: 8px;
}
.cluster-overview-grid .summary-item {
background:
linear-gradient(145deg, color-mix(in srgb, var(--card) 88%, var(--orange-400)) 0%, var(--card) 100%);
border-color: color-mix(in srgb, var(--orange-500) 22%, var(--border));
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
}
.cluster-overview-grid .summary-item strong {
font-size: 1.18rem;
letter-spacing: -0.02em;
color: var(--text);
}
.cluster-overview-grid .summary-label {
color: color-mix(in srgb, var(--muted) 82%, var(--orange-300));
}
.cluster-metric-donuts .metric-donut-item {
align-items: center;
justify-content: center;
gap: 10px;
}
.metric-donut {
--p: 0;
--ring-size: 96px;
width: var(--ring-size);
height: var(--ring-size);
border-radius: 50%;
display: grid;
place-items: center;
background:
radial-gradient(closest-side, var(--card) 72%, transparent 73% 100%),
conic-gradient(var(--orange-500) calc(var(--p) * 1%), color-mix(in srgb, var(--border) 86%, transparent) 0);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--orange-500) 20%, var(--border));
}
.metric-donut strong {
font-size: 0.92rem;
letter-spacing: -0.01em;
color: var(--text);
}
body[data-theme="light"] .metric-donut {
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--orange-500) 22%, #d7d1c8);
}
.summary-label {
color: var(--muted);
font-size: 0.65rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.summary-meta {
margin-top: 12px;
display: flex;
flex-wrap: wrap;
gap: 14px;
color: var(--muted);
font-size: 0.88rem;
}
.field-description { color: var(--muted); font-size: 0.8rem; line-height: 1.4; }
.form-output {
background: var(--bg);
border: 1px solid var(--border);
padding: 14px;
border-radius: var(--radius-md);
min-height: 60px;
white-space: pre-wrap;
font-family: var(--font-mono);
font-size: 0.82rem;
line-height: 1.45;
color: var(--text);
transition: opacity 0.2s ease;
}
.app-modal-overlay {
position: fixed;
inset: 0;
z-index: 500;
display: grid;
place-items: center;
background: rgba(10, 14, 24, 0.58);
backdrop-filter: blur(3px);
}
.app-modal-overlay.app-modal-overlay--fill {
display: flex;
align-items: center;
justify-content: center;
padding: 12px;
box-sizing: border-box;
}
.app-modal {
width: min(92vw, 480px);
border-radius: var(--radius-lg);
border: 1px solid var(--card-border);
background: var(--card);
box-shadow: 0 26px 60px rgba(0, 0, 0, 0.42);
padding: 18px 18px 14px;
}
.app-modal__title {
margin: 0 0 6px;
font-size: 1.02rem;
letter-spacing: -0.02em;
}
.app-modal__text {
margin: 0;
color: var(--muted);
white-space: pre-wrap;
}
.app-modal__actions {
margin-top: 14px;
display: flex;
justify-content: flex-end;
gap: 8px;
}
.form-output:empty { display: none; }
body[data-theme="light"] .form-output {
background: #ffffff;
border-color: var(--input-border);
color: var(--text);
}
/* Светлая тема: pre/code в формах — явно светлые поверхности (без тёмного color-mix) */
body[data-theme="light"] .audit-details > summary {
color: var(--muted);
}
body[data-theme="light"] .audit-details-pre,
body[data-theme="light"] .admin-json-block {
background: var(--form-surface-elevated);
color: var(--text);
border-color: var(--form-surface-elevated-border);
}
body[data-theme="light"] .dashboard-code-block {
background: var(--form-surface-elevated) !important;
border-color: var(--form-surface-elevated-border);
color: var(--text);
}
body[data-theme="light"] .schema-field-tip-panel {
color: var(--text);
background: var(--card);
border-color: var(--card-border);
}
.terminal {
background: #0a0c10;
color: #e8ecf4;
min-height: 280px;
max-height: 520px;
overflow: auto;
border-radius: var(--radius-md);
padding: 14px;
border: 1px solid var(--border);
font-family: var(--font-mono);
font-size: 0.82rem;
}
body[data-theme="light"] .terminal {
background: #f1f2f4;
color: var(--text);
border-color: #d4cec6;
}
canvas {
width: 100%;
border-radius: var(--radius-md);
background: var(--bg);
border: 1px solid var(--border);
}
body[data-theme="light"] canvas {
background: #ffffff;
border-color: var(--input-border);
}
.cluster-row {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
padding: 12px 0;
border-bottom: 1px solid var(--border);
}
.cluster-row a {
color: var(--orange-400);
font-weight: 600;
text-decoration: none;
}
.cluster-row a:hover { text-decoration: underline; }
.cluster-list-table .cluster-name-link {
color: var(--orange-400);
font-weight: 600;
text-decoration: none;
}
.cluster-list-table .cluster-name-link:hover { text-decoration: underline; }
.cluster-list-td-action { text-align: right; white-space: nowrap; justify-content: flex-end; }
.cluster-list-td-action .btn-muted { display: inline-flex; }
/* Theme toggle */
.theme-toggle { width: 100%; margin-bottom: 0; }
.theme-toggle-floating {
position: fixed;
top: 16px;
right: 18px;
width: 46px;
height: 46px;
border-radius: 999px;
margin: 0;
z-index: 60;
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 1.15rem;
border: 1px solid var(--card-border);
background: var(--card);
color: var(--text);
box-shadow: var(--shadow-card);
}
.theme-toggle-floating:hover {
transform: translateY(-2px);
border-color: var(--accent-border);
filter: none;
}
.toolbar-row { align-items: center; }
.tasks-table {
width: 100%;
border-collapse: collapse;
font-size: 0.88rem;
}
.tasks-table th, .tasks-table td {
padding: 12px 10px;
border-bottom: 1px solid var(--border);
text-align: left;
vertical-align: middle;
}
.tasks-table th {
color: var(--muted);
font-weight: 700;
font-size: 0.72rem;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.multi-select { min-height: 90px; min-width: 220px; }
.small-note { color: var(--muted); font-size: 0.8rem; margin: 8px 0 10px; }
.admin-os-toolbar {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
}
.admin-os-toolbar__actions {
justify-content: center;
width: 100%;
}
.admin-os-selectors {
border: 1px solid var(--card-border);
border-radius: 12px;
padding: 10px;
margin-bottom: 12px;
background: color-mix(in srgb, var(--card) 90%, transparent);
}
.admin-os-selectors__head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin-bottom: 8px;
}
.admin-os-selectors__actions {
display: inline-flex;
gap: 8px;
}
.admin-os-images-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 8px;
}
.admin-os-image-item {
border: 1px solid var(--card-border);
border-radius: 10px;
padding: 8px 10px;
background: color-mix(in srgb, var(--surface) 82%, transparent);
}
.admin-os-image-item label {
display: inline-flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.admin-os-image-item__meta {
margin-top: 6px;
color: var(--muted);
font-size: 0.8rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.admin-os-mini-card {
min-width: min(520px, 100%);
border: 1px solid var(--card-border);
border-radius: 12px;
padding: 8px 10px;
margin-bottom: 12px;
background: color-mix(in srgb, var(--card) 90%, transparent);
}
.admin-os-mini-card__top {
display: flex;
gap: 8px;
justify-content: space-between;
align-items: center;
margin-bottom: 6px;
}
.admin-os-mini-card__summary {
margin: 0;
text-align: right;
font-weight: 600;
color: color-mix(in srgb, var(--text) 78%, #38bdf8 22%);
}
.admin-os-mini-card__chips {
display: flex;
gap: 8px;
justify-content: flex-end;
flex-wrap: wrap;
}
.admin-os-mini-card__bar-wrap {
margin-top: 8px;
height: 8px;
border-radius: 999px;
background: color-mix(in srgb, var(--border) 70%, transparent);
overflow: hidden;
}
.admin-os-mini-card__state {
font-size: 0.82rem;
font-weight: 700;
letter-spacing: 0.02em;
text-transform: uppercase;
}
.admin-os-build-status__chip {
border: 1px solid transparent;
border-radius: 999px;
padding: 3px 10px;
font-size: 0.79rem;
font-weight: 600;
}
.admin-os-build-status__chip strong {
font-size: 0.82rem;
}
.admin-os-build-status__chip--built {
color: #16a34a;
border-color: color-mix(in srgb, #16a34a 40%, transparent);
background: color-mix(in srgb, #16a34a 12%, transparent);
}
.admin-os-build-status__chip--failed {
color: #dc2626;
border-color: color-mix(in srgb, #dc2626 40%, transparent);
background: color-mix(in srgb, #dc2626 12%, transparent);
}
.admin-os-build-status__chip--total {
color: #2563eb;
border-color: color-mix(in srgb, #2563eb 40%, transparent);
background: color-mix(in srgb, #2563eb 12%, transparent);
}
.admin-os-state--idle { color: #94a3b8; }
.admin-os-state--running { color: #38bdf8; }
.admin-os-state--success { color: #22c55e; }
.admin-os-state--failed { color: #ef4444; }
.admin-os-state--stopped { color: #f59e0b; }
.admin-os-build-status__bar-wrap {
height: 8px;
border-radius: 999px;
background: color-mix(in srgb, var(--border) 70%, transparent);
overflow: hidden;
}
.admin-os-build-status__bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #38bdf8, #22c55e);
transition: width 0.2s ease;
}
.tasks-actions {
display: inline-flex;
gap: 8px;
flex-wrap: nowrap;
align-items: center;
white-space: nowrap;
}
.btn-icon {
box-sizing: border-box;
width: 30px;
height: 30px;
min-width: 30px;
max-width: 30px;
min-height: 30px;
max-height: 30px;
padding: 0;
border-radius: 9px;
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
cursor: pointer;
border: 1px solid transparent;
flex: 0 0 30px;
font-size: 0;
font-weight: normal;
line-height: 1;
box-shadow: none;
-webkit-appearance: none;
appearance: none;
}
.btn-icon--open {
color: #8ec5ff;
border-color: rgba(59, 130, 246, 0.55);
background: linear-gradient(145deg, rgba(59, 130, 246, 0.2), rgba(59, 130, 246, 0.08));
}
.btn-icon--open:hover {
color: #d6eaff;
border-color: rgba(147, 197, 253, 0.75);
}
.btn-icon--add {
color: #fdba74;
border-color: rgba(249, 115, 22, 0.6);
background: linear-gradient(145deg, rgba(249, 115, 22, 0.22), rgba(249, 115, 22, 0.08));
}
.btn-icon--add:hover {
color: #ffedd5;
border-color: rgba(251, 146, 60, 0.78);
}
.btn-icon--export {
color: #86efac;
border-color: rgba(34, 197, 94, 0.58);
background: linear-gradient(145deg, rgba(34, 197, 94, 0.22), rgba(34, 197, 94, 0.08));
}
.btn-icon--export:hover {
color: #dcfce7;
border-color: rgba(74, 222, 128, 0.78);
}
.btn-icon--catalog-danger {
color: #fca5a5;
border-color: rgba(248, 113, 113, 0.55);
background: linear-gradient(145deg, rgba(248, 113, 113, 0.2), rgba(248, 113, 113, 0.07));
}
.btn-icon--catalog-danger:hover {
color: #fecaca;
border-color: rgba(252, 165, 165, 0.78);
}
.btn-icon svg {
width: 16px;
height: 16px;
}
.btn-icon i {
font-size: 0.92rem;
line-height: 1;
}
.btn-icon[data-tooltip] {
position: relative;
}
.btn-icon[data-tooltip]::before {
content: "";
position: absolute;
left: 50%;
bottom: calc(100% + 2px);
width: 8px;
height: 8px;
background: color-mix(in srgb, var(--bg-panel) 86%, #000);
border-left: 1px solid var(--border);
border-top: 1px solid var(--border);
transform: translateX(-50%) rotate(225deg) translateY(-2px);
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease, transform 0.15s ease;
z-index: 40;
}
.btn-icon[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
left: 50%;
bottom: calc(100% + 8px);
transform: translateX(-50%) translateY(4px);
background: linear-gradient(
140deg,
color-mix(in srgb, var(--bg-panel) 90%, #111) 0%,
color-mix(in srgb, var(--bg-elevated) 88%, #000) 100%
);
color: var(--text);
border: 1px solid var(--border);
border-radius: 6px;
padding: 5px 9px;
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.02em;
line-height: 1.2;
white-space: nowrap;
opacity: 0;
pointer-events: none;
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.28);
transition: opacity 0.15s ease, transform 0.15s ease;
z-index: 40;
}
.btn-icon[data-tooltip]:hover::before,
.btn-icon[data-tooltip]:focus-visible::before {
opacity: 1;
transform: translateX(-50%) rotate(225deg) translateY(0);
}
.btn-icon[data-tooltip]:hover::after,
.btn-icon[data-tooltip]:focus-visible::after {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
.btn-muted {
background: transparent;
border-color: var(--input-border);
color: var(--text);
box-shadow: none;
}
.btn-muted:hover {
background: var(--hover);
border-color: var(--orange-400);
color: var(--text);
filter: none;
}
.btn-sm {
font-size: 0.82rem;
padding: 0.2rem 0.55rem;
}
.btn-danger {
background: linear-gradient(135deg, #ef4444, #dc2626);
border-color: #b91c1c;
color: #fff;
box-shadow: 0 2px 10px rgba(220, 38, 38, 0.25);
}
.pagination-row { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.console-toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.checkline {
display: inline-flex;
gap: 0.625rem;
align-items: center;
color: var(--text);
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
user-select: none;
}
.checkline input[type="checkbox"] {
flex-shrink: 0;
}
.checkline-modern {
background: var(--bg-panel);
border: 2px solid var(--border);
border-radius: var(--radius-md);
padding: 12px 14px;
width: fit-content;
transition: var(--form-transition);
}
.checkline-modern:hover {
border-color: color-mix(in srgb, var(--border) 70%, var(--orange-400));
}
.choice-row { display: flex; flex-wrap: wrap; gap: 0.625rem; }
/* Modern segmented radio (e.g. Molecule test scope) */
.radio-segment-group {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 6px;
border-radius: var(--radius-lg);
background: color-mix(in srgb, var(--bg) 88%, var(--card));
border: 1px solid var(--border);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.12);
}
body[data-theme="light"] .radio-segment-group {
box-shadow: inset 0 1px 2px rgba(26, 29, 36, 0.06);
}
.radio-segment {
position: relative;
flex: 1 1 140px;
min-width: 0;
cursor: pointer;
border-radius: var(--radius-md);
}
.radio-segment input[type="radio"] {
position: absolute;
inset: 0;
z-index: 2;
width: 100%;
height: 100%;
margin: 0;
min-width: 0;
min-height: 0;
opacity: 0;
cursor: pointer;
appearance: none;
-webkit-appearance: none;
border: none !important;
background: transparent !important;
box-shadow: none !important;
}
.radio-segment input[type="radio"]:hover,
.radio-segment input[type="radio"]:checked,
.radio-segment input[type="radio"]:focus {
background-image: none !important;
outline: none !important;
}
.radio-segment-face {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
min-height: 4.5rem;
padding: 14px 12px;
border-radius: var(--radius-md);
text-align: center;
border: 1px solid transparent;
background: var(--card);
color: var(--muted);
transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease;
pointer-events: none;
}
.radio-segment:hover input:not(:checked) + .radio-segment-face {
color: var(--text);
border-color: color-mix(in srgb, var(--border) 70%, var(--orange-400));
background: var(--bg-elevated);
}
.radio-segment input:checked + .radio-segment-face {
background: linear-gradient(145deg, var(--orange-400) 0%, var(--orange-500) 42%, var(--orange-600) 100%);
color: #fff;
border-color: rgba(255, 255, 255, 0.22);
box-shadow: 0 6px 20px rgba(249, 115, 22, 0.32);
transform: translateY(-1px);
}
.radio-segment-title {
font-size: 0.92rem;
font-weight: 700;
letter-spacing: -0.02em;
line-height: 1.25;
}
.radio-segment-desc {
font-size: 0.72rem;
font-weight: 500;
line-height: 1.35;
opacity: 0.92;
}
.radio-segment input:checked + .radio-segment-face .radio-segment-desc {
opacity: 0.88;
color: rgba(255, 255, 255, 0.92);
}
.radio-segment:has(input:focus-visible) .radio-segment-face {
outline: 2px solid var(--orange-400);
outline-offset: 2px;
}
.radio-segment-title--with-icon {
display: inline-flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 0.35rem 0.45rem;
}
.radio-segment-icon {
font-size: 1.08rem;
opacity: 0.92;
line-height: 1;
}
.radio-segment input:checked + .radio-segment-face .radio-segment-icon {
opacity: 1;
}
.radio-segment--disabled,
.radio-segment:has(input:disabled) {
cursor: not-allowed;
}
.radio-segment--disabled input[type="radio"],
.radio-segment:has(input:disabled) input[type="radio"] {
cursor: not-allowed;
}
.radio-segment--disabled .radio-segment-face,
.radio-segment:has(input:disabled) .radio-segment-face {
opacity: 0.82;
filter: saturate(0.88);
}
.radio-segment--disabled:hover .radio-segment-face,
.radio-segment:has(input:disabled):hover .radio-segment-face {
border-color: transparent;
background: var(--card);
color: var(--muted);
transform: none;
}
.role-vis-soon-badge {
display: inline-flex;
align-items: center;
font-size: 0.62rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.07em;
padding: 3px 7px;
border-radius: 999px;
background: color-mix(in srgb, var(--muted) 22%, transparent);
border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
color: var(--muted);
line-height: 1;
}
.role-visibility-segments {
margin-top: 6px;
}
.role-visibility-footnote {
margin: 10px 0 0;
max-width: 52rem;
line-height: 1.45;
}
.toggle-chip {
display: inline-flex;
align-items: center;
gap: 0.625rem;
padding: 0.65rem 1rem;
border-radius: 999px;
border: 2px solid var(--input-border);
background: var(--form-check-bg);
color: var(--text);
cursor: pointer;
font-size: 0.9rem;
font-weight: 500;
transition: var(--form-transition);
}
.toggle-chip:hover {
border-color: color-mix(in srgb, var(--input-border) 65%, var(--orange-400));
}
.toggle-chip:has(input:focus-visible) {
outline: none;
box-shadow: var(--form-focus-ring);
}
.toggle-chip:has(input:checked) {
border-color: var(--orange-500);
background: linear-gradient(90deg, var(--accent-soft), rgba(249, 115, 22, 0.06));
box-shadow: 0 0 0 1px rgba(249, 115, 22, 0.15);
}
.toggle-chip--disabled {
opacity: 0.55;
cursor: not-allowed;
}
.terminal-large {
min-height: 420px;
max-height: 70vh;
width: 100%;
max-width: 100%;
overflow-x: auto;
box-sizing: border-box;
}
.layout[data-page="task-console"] .content {
max-width: none;
width: 100%;
}
.layout[data-page="task-console"] .card {
width: 100%;
}
.task-line-hidden { display: none; }
.status-badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 700;
border: 1px solid transparent;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.status-running {
background: rgba(249, 115, 22, 0.15);
border-color: rgba(251, 146, 60, 0.45);
color: var(--orange-300);
}
.status-success {
background: rgba(34, 197, 94, 0.12);
border-color: rgba(74, 222, 128, 0.4);
color: #86efac;
}
.status-failed {
background: rgba(239, 68, 68, 0.12);
border-color: rgba(248, 113, 113, 0.45);
color: #fca5a5;
}
.status-pending {
background: rgba(148, 163, 184, 0.12);
border-color: rgba(148, 163, 184, 0.35);
color: #cbd5e1;
}
.status-retrying {
background: rgba(250, 204, 21, 0.12);
border-color: rgba(250, 204, 21, 0.4);
color: #fde047;
}
/* —— Public / auth —— */
.public-layout {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 28px 20px;
background:
radial-gradient(ellipse 100% 80% at 50% -30%, rgba(249, 115, 22, 0.18), transparent 55%),
var(--bg);
}
body[data-theme="light"] .public-layout {
background:
radial-gradient(ellipse 100% 70% at 50% -20%, rgba(251, 146, 60, 0.22), transparent 50%),
var(--bg);
}
.public-card {
width: 100%;
max-width: 440px;
background: var(--card);
border: 1px solid var(--card-border);
border-radius: var(--radius-lg);
padding: 28px 26px;
box-shadow: var(--shadow-card);
animation: fade-in 0.4s ease;
}
.public-card .card {
margin-top: 12px;
border-radius: var(--radius-lg);
background: var(--bg-elevated);
border-color: var(--card-border);
}
.auth-form {
display: flex;
flex-direction: column;
gap: 0;
margin-bottom: 14px;
}
.auth-form input[type="text"],
.auth-form input[type="email"],
.auth-form input[type="password"] {
width: 100%;
min-width: 0;
min-height: 3rem;
padding: 0.75rem 1rem;
}
.auth-submit {
width: 100%;
margin-top: 8px;
height: 48px;
border-radius: var(--radius-md);
font-size: 0.95rem;
}
.auth-links { margin-top: 10px; font-size: 0.9rem; }
.auth-links a { color: var(--orange-400); font-weight: 600; text-decoration: none; }
.auth-links a:hover { text-decoration: underline; color: var(--orange-300); }
/* —— Error pages —— */
.error-page {
margin-top: 24px;
padding: 36px 30px;
border-radius: var(--radius-lg);
border: 1px solid var(--card-border);
background: var(--card);
box-shadow: var(--shadow-card);
}
.error-page--below-hero {
margin-top: 0;
padding-top: 28px;
}
.error-code {
font-size: clamp(3rem, 10vw, 4.25rem);
font-weight: 800;
line-height: 1;
letter-spacing: -0.02em;
background: linear-gradient(135deg, var(--orange-300), var(--orange-600));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 12px;
}
.error-title { margin: 0 0 10px; font-size: 1.75rem; font-weight: 800; }
.error-description { margin: 0 0 18px; color: var(--muted); max-width: 640px; line-height: 1.55; }
.error-actions { display: flex; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.error-btn-primary, .error-btn-secondary {
text-decoration: none;
padding: 11px 18px;
border-radius: var(--radius-md);
font-weight: 600;
display: inline-flex;
align-items: center;
}
.error-btn-primary {
background: linear-gradient(135deg, var(--orange-400), var(--orange-600));
color: #fff;
border: 1px solid rgba(234, 88, 12, 0.5);
}
.error-btn-secondary {
background: transparent;
border: 1px solid var(--input-border);
color: var(--text);
}
.skeleton {
position: relative;
overflow: hidden;
background: rgba(148, 163, 184, 0.12);
border-radius: var(--radius-md);
color: transparent !important;
}
.skeleton::after {
content: "";
position: absolute;
inset: 0;
transform: translateX(-100%);
background: linear-gradient(90deg, transparent, rgba(249, 115, 22, 0.12), transparent);
animation: shimmer 1.2s infinite;
}
body[data-theme="light"] .skeleton {
background: rgba(26, 29, 36, 0.07);
}
body[data-theme="light"] .skeleton::after {
background: linear-gradient(90deg, transparent, rgba(249, 115, 22, 0.14), transparent);
}
@keyframes shimmer { 100% { transform: translateX(100%); } }
@keyframes fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
/* —— Provisioning: separate URLs, one form —— */
.provmod--k3s .prov-sec--gvh,
.provmod--k3s .prov-sec--host,
.provmod--k3s .prov-sec--nodes,
.provmod--k3s .prov-sec--addonen { display: none !important; }
.provmod--group-all .prov-sec--k3s,
.provmod--group-all .prov-sec--host,
.provmod--group-all .prov-sec--nodes,
.provmod--group-all .prov-sec--addonen { display: none !important; }
.provmod--group-all #cluster-provisioning-gv .gv-sec[data-gv-sec="addons"],
.provmod--group-all #cluster-provisioning-gv .gv-sec[data-gv-sec="vault"],
.provmod--group-all #cluster-provisioning-gv .schema-field--inventory { display: none !important; }
.provmod--group-addons .prov-sec--k3s,
.provmod--group-addons .prov-sec--host,
.provmod--group-addons .prov-sec--nodes,
.provmod--group-addons .prov-sec--addonen { display: none !important; }
.provmod--group-addons #cluster-provisioning-gv .gv-sec[data-gv-sec="all"],
.provmod--group-addons #cluster-provisioning-gv .gv-sec[data-gv-sec="vault"],
.provmod--group-addons #cluster-provisioning-gv .schema-field--inventory { display: none !important; }
.provmod--group-vault .prov-sec--k3s,
.provmod--group-vault .prov-sec--host,
.provmod--group-vault .prov-sec--nodes,
.provmod--group-vault .prov-sec--addonen { display: none !important; }
.provmod--group-vault #cluster-provisioning-gv .gv-sec[data-gv-sec="all"],
.provmod--group-vault #cluster-provisioning-gv .gv-sec[data-gv-sec="addons"],
.provmod--group-vault #cluster-provisioning-gv .schema-field--inventory { display: none !important; }
.provmod--inventory .prov-sec--k3s,
.provmod--inventory .prov-sec--host,
.provmod--inventory .prov-sec--addonen { display: none !important; }
.provmod--inventory #cluster-provisioning-gv .gv-sec[data-gv-sec="all"],
.provmod--inventory #cluster-provisioning-gv .gv-sec[data-gv-sec="addons"],
.provmod--inventory #cluster-provisioning-gv .gv-sec[data-gv-sec="vault"] { display: none !important; }
.provmod--host-vars .prov-sec--k3s,
.provmod--host-vars .prov-sec--gvh,
.provmod--host-vars .prov-sec--nodes,
.provmod--host-vars .prov-sec--addonen { display: none !important; }
.provmod--addons-enable .prov-sec--k3s,
.provmod--addons-enable .prov-sec--gvh,
.provmod--addons-enable .prov-sec--host,
.provmod--addons-enable .prov-sec--nodes { display: none !important; }
.provmod--k3s #cluster-dryrun-btn,
.provmod--k3s #cluster-molecule-btn,
.provmod--k3s #cluster-bootstrap-btn,
.provmod--group-all #cluster-dryrun-btn,
.provmod--group-all #cluster-molecule-btn,
.provmod--group-all #cluster-bootstrap-btn,
.provmod--group-addons #cluster-dryrun-btn,
.provmod--group-addons #cluster-molecule-btn,
.provmod--group-addons #cluster-bootstrap-btn,
.provmod--group-vault #cluster-dryrun-btn,
.provmod--group-vault #cluster-molecule-btn,
.provmod--group-vault #cluster-bootstrap-btn,
.provmod--inventory #cluster-dryrun-btn,
.provmod--inventory #cluster-molecule-btn,
.provmod--inventory #cluster-bootstrap-btn,
.provmod--host-vars #cluster-dryrun-btn,
.provmod--host-vars #cluster-molecule-btn,
.provmod--host-vars #cluster-bootstrap-btn,
.provmod--addons-enable #cluster-dryrun-btn,
.provmod--addons-enable #cluster-molecule-btn,
.provmod--addons-enable #cluster-bootstrap-btn { display: none !important; }
.provmod--k3s #cluster-add-hostvar-btn,
.provmod--k3s #cluster-add-node-btn,
.provmod--group-all #cluster-add-hostvar-btn,
.provmod--group-all #cluster-add-node-btn,
.provmod--group-addons #cluster-add-hostvar-btn,
.provmod--group-addons #cluster-add-node-btn,
.provmod--group-vault #cluster-add-hostvar-btn,
.provmod--group-vault #cluster-add-node-btn,
.provmod--inventory #cluster-add-hostvar-btn,
.provmod--inventory #cluster-add-node-btn,
.provmod--host-vars #cluster-add-hostvar-btn,
.provmod--host-vars #cluster-add-node-btn,
.provmod--addons-enable #cluster-add-hostvar-btn,
.provmod--addons-enable #cluster-add-node-btn { display: none !important; }
.addons-enable-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 8px;
}
/* Molecule one-template sub-pages */
.layout.molmod--run .mol-sec:not([data-mol="run"]),
.layout.molmod--details .mol-sec:not([data-mol="details"]),
.layout.molmod--reports .mol-sec:not([data-mol="reports"]) { display: none !important; }
/* RBAC / access / ops one-template sub-pages */
.layout.rbmod--users .crbac-sec:not([data-crbac="users"]),
.layout.rbmod--namespaces .crbac-sec:not([data-crbac="namespaces"]),
.layout.rbmod--reconcile .crbac-sec:not([data-crbac="reconcile"]) { display: none; }
.layout.accmod--request .cacc-sec:not([data-cacc="request"]),
.layout.accmod--queue .cacc-sec:not([data-cacc="queue"]),
.layout.accmod--impersonation .cacc-sec:not([data-cacc="impersonation"]),
.layout.accmod--permissions .cacc-sec:not([data-cacc="permissions"]) { display: none; }
.layout.opsmod--service-accounts .cops-sec:not([data-cops="service-accounts"]),
.layout.opsmod--api .cops-sec:not([data-cops="api"]),
.layout.opsmod--jobs .cops-sec:not([data-cops="jobs"]) { display: none; }
/* Sidebar: collapsible — визуально как рядом стоящий a.menu-link; обёртка без рамки/фона */
.menu-accordion {
margin: 0;
}
.menu-accordion__toggle {
margin-left: auto;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
flex: 0 0 20px;
color: inherit;
opacity: 0.72;
pointer-events: none;
}
.menu-accordion__toggle svg {
width: 16px;
height: 16px;
display: block;
transition: transform 0.2s ease;
}
/* Закрыто: стрелка вниз; открыто: вверх (svg — chevron down, на :open поворот 180°) */
.menu-accordion.is-open .menu-accordion__toggle svg {
transform: rotate(180deg);
}
.menu-accordion__panel { padding: 0 0 0.15rem; margin-top: 0.1rem; }
.menu-accordion__panel > .menu-sublink:first-of-type { margin-top: 0; }
.menu-accordion__panel > .menu-sublink {
margin-left: 1rem;
padding-left: 1rem;
}
.sidebar-clusters-tree > .menu-sublink {
margin-left: 1rem;
padding-left: 1rem;
}
.sidebar-clusters-tree > .menu-accordion.menu-accordion--cluster {
margin-left: 1rem;
}
.sidebar-clusters-tree > .menu-accordion > .menu-accordion__head--cluster {
padding-left: 1rem;
}
.menu-accordion:not(.is-open) .menu-accordion__panel {
display: none;
}
.menu-accordion__panel .menu-nested--tree {
margin: 0;
padding: 0 0 0 0.2rem;
border-left-width: 0;
border-left-color: transparent;
}
/* Sidebar: nested + cluster tree (JS) */
.menu-nested--tree { font-size: 0.9rem; margin: 0 0 0.4rem; padding: 0 0 0 0.2rem; border-left: 0 solid transparent; }
.menu-eyebrow, .menu-tree-eyebrow { display: block; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted, #8b9bb4); margin: 0.75rem 0 0.25rem; }
.menu-sublink { display: flex; align-items: center; gap: 0.45rem; padding: 0.28rem 0 0.28rem 0.4rem; font-size: 0.88rem; text-decoration: none; color: var(--text, #e6edf7); border-radius: 6px; }
.menu-sublink::before {
content: "";
width: 0.72rem;
height: 0.72rem;
border: 1.5px solid currentColor;
border-radius: 3px;
opacity: 0.7;
flex: 0 0 auto;
}
.menu-sublink--with-icon::before {
content: none;
display: none;
width: 0;
height: 0;
border: 0;
}
.menu-sublink__icon {
flex: 0 0 1.05rem;
width: 1.05rem;
height: 1.05rem;
display: flex;
align-items: center;
justify-content: center;
color: currentColor;
opacity: 0.82;
}
.menu-sublink__icon svg {
width: 100%;
height: 100%;
display: block;
stroke: currentColor;
fill: none;
}
.menu-sublink__icon i {
font-size: 0.95rem;
line-height: 1;
}
.menu-sublink:hover .menu-sublink__icon,
.menu-sublink.active .menu-sublink__icon { opacity: 1; }
.menu-sublink__label { min-width: 0; flex: 1; }
.menu-sublink.active::before { opacity: 1; }
.menu-sublink:hover { background: rgba(249, 115, 22, 0.08); }
.menu-accordion--cluster .menu-nested--tree .menu-sublink {
padding-left: 1rem;
}
.menu-accordion--cluster .menu-nested--tree .menu-sublink.active {
color: #fff;
background: linear-gradient(90deg, rgba(249, 115, 22, 0.2), rgba(249, 115, 22, 0.06));
box-shadow: 0 0 0 1px rgba(249, 115, 22, 0.12);
}
.menu-link--bleed { width: 100%; text-align: left; background: none; border: 0; cursor: pointer; font: inherit; color: inherit; }
.menu-tree-block { margin: 0.35rem 0 0.4rem; padding: 0 0 0 0.3rem; border-left: 1px solid rgba(148, 163, 184, 0.2); }
a.menu-tree-cluster {
display: flex;
align-items: center;
gap: 0.45rem;
font-size: 0.95rem;
font-weight: 600;
margin: 0.2rem 0;
text-decoration: none;
color: inherit;
}
a.menu-tree-cluster .menu-sublink__icon { flex: 0 0 1.1rem; width: 1.1rem; height: 1.1rem; }
a.menu-tree-cluster::before { content: none; display: none; }
.menu-tree-block > .menu-tree-cluster:first-child { margin-top: 0; }
.menu-tree-subl { display: block; font-size: 0.8rem; padding: 0.1rem 0; color: var(--text-muted, #94a3b8); }
.sidebar-tree-placeholder { display: none; }
@media (max-width: 1024px) {
.layout { grid-template-columns: 1fr; }
.sidebar {
border-right: none;
border-bottom: 1px solid var(--border);
box-shadow: none;
}
.sidebar::before { width: 100%; height: 3px; inset: auto 0 0 0; }
.sidebar-inner { padding-bottom: 20px; }
.card-grid, .summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
#addon-schema-fields, #cluster-schema-fields, .schema-grid { grid-template-columns: 1fr; }
.form-actions { justify-content: stretch; }
.form-actions button { width: 100%; }
}
@media (max-width: 640px) {
.content { padding: 20px 16px 32px; }
.card-grid, .summary-grid { grid-template-columns: 1fr; }
}