/* * WESP admin UI — слой поверх Ant Design (MIT) из /static/vendor/admin-ui/ * antd.min.css, custom.min.css * * Ниже — переключение вкладок, кольца метрик и мелкие дополнения. */ /* Как в web/html/common/page.html — горизонтальный скролл вкладок на мобильных */ @media (max-width: 576px) { .ant-tabs-nav-container { overflow-x: auto !important; -webkit-overflow-scrolling: touch; scroll-behavior: smooth; overscroll-behavior-x: contain; white-space: nowrap; max-width: 100%; padding: 0 !important; } .ant-tabs-nav-wrap { overflow: visible !important; padding: 0 !important; } .ant-tabs-nav-scroll { overflow: visible !important; box-shadow: none !important; } .ant-tabs-nav { display: flex !important; transform: none !important; width: auto !important; margin: 0 !important; } .ant-tabs-tab-prev, .ant-tabs-tab-next { display: none !important; } .ant-tabs-nav-container::-webkit-scrollbar { display: none; } } body { margin: 0; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; } /* —— Скелетон (ранний inline-скрипт + мин. время показа в JS) и появление блоков —— */ .wesp-admin-block { position: relative; } html.wesp-admin-loading #app { pointer-events: none; } .wesp-admin-skel-overlay { position: absolute; inset: 0; z-index: 5; pointer-events: none; border-radius: inherit; background: linear-gradient( 105deg, rgba(0, 0, 0, 0.07) 0%, rgba(0, 0, 0, 0.07) 34%, rgba(0, 0, 0, 0.18) 50%, rgba(0, 0, 0, 0.07) 66%, rgba(0, 0, 0, 0.07) 100% ); background-size: 240% 100%; animation: wesp-admin-skel-shimmer 0.95s ease-in-out infinite; opacity: 1; transition: opacity 0.38s ease; } html.dark .wesp-admin-skel-overlay, html[data-theme="ultra-dark"] .wesp-admin-skel-overlay { background: linear-gradient( 105deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.06) 34%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.06) 66%, rgba(255, 255, 255, 0.06) 100% ); background-size: 240% 100%; } @keyframes wesp-admin-skel-shimmer { 0% { background-position: 240% 0; } 100% { background-position: -240% 0; } } html.wesp-admin-loaded .wesp-admin-skel-overlay { opacity: 0; } html.wesp-admin-loading .wesp-admin-block { animation: none; } html.wesp-admin-loaded .wesp-admin-block { animation: wesp-admin-block-reveal 0.52s cubic-bezier(0.22, 1, 0.36, 1) both; animation-delay: calc(var(--wesp-reveal-i, 0) * 38ms); } @keyframes wesp-admin-block-reveal { from { opacity: 0.55; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } } @keyframes wesp-admin-section-tween { from { opacity: 0.4; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } html.wesp-admin-loaded .wesp-admin-block.wesp-admin-section-enter { animation: wesp-admin-section-tween 0.44s cubic-bezier(0.22, 1, 0.36, 1) both; animation-delay: calc(var(--wesp-reveal-i, 0) * 28ms); } .wesp-admin-content-topbar.wesp-admin-block { min-height: 44px; } /* Полная настройка киоска — экран как /starting */ .wesp-kiosk-setup-overlay { position: fixed; inset: 0; z-index: 200000; display: none; } .wesp-kiosk-setup-overlay:not([hidden]) { display: block; } .wesp-kiosk-setup-overlay__screen.wesp-startup-screen { min-height: 100vh; margin: 0; background: #12181b; color: #ffffff; } .wesp-kiosk-setup-overlay .wesp-startup__quip { color: #a8b0b8; } .wesp-kiosk-setup-overlay .wesp-startup__quip--error { color: #ff7875; } @media (prefers-reduced-motion: reduce) { .wesp-admin-skel-overlay { animation: none !important; opacity: 0.85; } html.wesp-admin-loaded .wesp-admin-block { animation: none !important; opacity: 1 !important; transform: none !important; } html.wesp-admin-loaded .wesp-admin-block.wesp-admin-section-enter { animation: none !important; } } /* Карточки счётчиков на дашборде: переход в раздел / приложение */ .wesp-admin-stat-card--clickable { cursor: pointer; outline: none; transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease; } .wesp-admin-stat-card--clickable:hover { border-color: rgba(24, 144, 255, 0.55); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); } .wesp-admin-stat-card--clickable:active { transform: translateY(1px); } .wesp-admin-stat-card--clickable:focus-visible { box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.35); } html.dark .wesp-admin-stat-card--clickable:hover, html[data-theme="ultra-dark"] .wesp-admin-stat-card--clickable:hover { border-color: rgba(64, 169, 255, 0.5); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35); } /* * Фон области контента: тёмная подложка задаётся селектором .dark > .ant-layout, * но у них class="dark" на корневом блоке приложения, а не на . * У Ant Design у .ant-layout по умолчанию background: #f0f2f5 — без этого правило «белеет». */ html.dark body { background-color: var(--dark-color-background); color: var(--dark-color-text-primary); } html.dark #app.ant-layout.ant-layout-has-sider, html.dark #app.ant-layout-has-sider > .ant-layout { background: var(--dark-color-background) !important; } html.dark .ant-layout-content { background: transparent !important; } html.light body { background-color: #f0f2f5; } /* Вкладки контента (не путать с классами Ant) */ .wesp-admin-section { display: none !important; } .wesp-admin-section.is-active { display: block !important; } /* Верхняя панель контента (кнопки справа) */ .wesp-admin-content-topbar { display: flex; justify-content: flex-end; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 16px; } .wesp-admin-content-topbar-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; } /* Заголовок сайдбара (без логотипа): анимация высоты — меню едет вниз/вверх */ .wesp-admin-sider .ant-layout-sider-children { overflow: hidden; } .wesp-admin-brand { padding: 16px 12px 14px; text-align: center; border-bottom: 1px solid var(--border-faint, rgba(65, 85, 119, 0.5)); max-height: 5.5rem; opacity: 1; overflow: hidden; transition: max-height 0.38s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.32s ease, padding 0.38s cubic-bezier(0.4, 0, 0.2, 1), border-bottom-color 0.28s ease, margin 0.32s ease; } .wesp-admin-brand-title { font-weight: 600; font-size: 15px; letter-spacing: 0.04em; transform: translateY(0); opacity: 1; transition: transform 0.34s cubic-bezier(0.34, 1.15, 0.64, 1) 0.06s, opacity 0.28s ease 0.08s; } .wesp-admin-sider.ant-layout-sider-collapsed .wesp-admin-brand-title { transform: translateY(-10px); opacity: 0; transition: transform 0.22s ease, opacity 0.18s ease; } /* Пункт меню: иконка (inline SVG) + подпись */ .wesp-admin-sider .ant-menu-item { cursor: pointer; margin-top: 4px; margin-bottom: 4px; display: flex !important; align-items: center; gap: 10px; } .wesp-menu-icon { display: inline-flex; flex-shrink: 0; width: 1.125rem; height: 1.125rem; align-items: center; justify-content: center; } .wesp-menu-icon svg { width: 100%; height: 100%; display: block; } /* Ширина сайдбара и узкий режим (Ant Design) */ .wesp-admin-sider.ant-layout-sider { flex: 0 0 256px !important; max-width: 256px !important; min-width: 256px !important; width: 256px !important; transition: flex 0.38s cubic-bezier(0.4, 0, 0.2, 1), max-width 0.38s cubic-bezier(0.4, 0, 0.2, 1), min-width 0.38s cubic-bezier(0.4, 0, 0.2, 1), width 0.38s cubic-bezier(0.4, 0, 0.2, 1) !important; } .wesp-admin-sider.ant-layout-sider.ant-layout-sider-collapsed { flex: 0 0 80px !important; max-width: 80px !important; min-width: 80px !important; width: 80px !important; } .wesp-admin-sider .ant-layout-sider-trigger { position: absolute; left: 0; right: 0; bottom: 0; width: 100% !important; } .wesp-sider-trigger-icon { display: inline-block; font-size: 12px; opacity: 0.9; } /* collapsed и wesp-admin-sider на одном aside — только составной селектор */ .wesp-admin-sider.ant-layout-sider-collapsed .wesp-admin-brand { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; margin: 0; border-bottom-color: transparent; pointer-events: none; } .wesp-admin-sider .wesp-menu-label { min-width: 0; overflow: hidden; white-space: nowrap; max-width: 16rem; opacity: 1; transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1) 0.1s, max-width 0.36s cubic-bezier(0.4, 0, 0.2, 1) 0.08s, margin 0.25s ease, padding 0.25s ease; } .wesp-admin-sider.ant-layout-sider-collapsed .wesp-menu-label { max-width: 0 !important; opacity: 0 !important; margin: 0 !important; padding: 0 !important; transition: opacity 0.22s ease, max-width 0.32s cubic-bezier(0.4, 0, 0.2, 1), margin 0.2s ease, padding 0.2s ease; pointer-events: none; } .wesp-admin-sider.ant-layout-sider-collapsed .ant-menu-item { justify-content: center; gap: 0; padding-left: 0 !important; padding-right: 0 !important; transition: padding 0.32s cubic-bezier(0.4, 0, 0.2, 1), justify-content 0.2s ease; } .wesp-admin-sider:not(.ant-layout-sider-collapsed) .ant-menu-item { transition: padding 0.34s cubic-bezier(0.4, 0, 0.2, 1) 0.06s, gap 0.25s ease 0.04s; } @media (prefers-reduced-motion: reduce) { .wesp-admin-sider.ant-layout-sider, .wesp-admin-brand, .wesp-admin-brand-title, .wesp-admin-sider .wesp-menu-label, .wesp-admin-sider .ant-menu-item { transition: none !important; } .wesp-admin-sider.ant-layout-sider-collapsed .wesp-admin-brand-title { transform: none; } } /* Отступ между карточками */ .wesp-admin-card-gap { margin-bottom: 16px; } /* —— Кольца ресурсов (аналог ant-progress circle) —— */ .wesp-gauge { --gauge-circ: 295.31; --gauge-pct: 0; text-align: center; } .wesp-gauge-ring { position: relative; width: 120px; max-width: 100%; margin: 0 auto; aspect-ratio: 1; } .wesp-gauge-svg { width: 100%; height: 100%; display: block; } .wesp-gauge-track { stroke: var(--gauge-track, #313f5a); } /* В ultra-dark custom.min.css задаёт другие --dark-color-*; кольцо ближе к скроллбару */ html[data-theme="ultra-dark"] .wesp-gauge-track { stroke: var(--dark-color-scrollbar); } .wesp-gauge-fill { stroke: var(--color-primary-100, #008771); stroke-dasharray: var(--gauge-circ); stroke-dashoffset: calc(var(--gauge-circ) * (1 - var(--gauge-pct) / 100)); transition: stroke-dashoffset 0.45s ease; } @media (prefers-reduced-motion: reduce) { .wesp-gauge-fill { transition: none; } } .wesp-gauge-center { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none; } .wesp-gauge-pct { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; } .wesp-gauge-pct-suffix { font-size: 13px; font-weight: 600; opacity: 0.55; margin-left: 1px; } .wesp-gauge-name { margin-top: 10px; font-size: 14px; font-weight: 600; } .wesp-gauge-detail { margin-top: 4px; font-size: 12px; opacity: 0.55; line-height: 1.35; word-break: break-word; } /* Круги метрик: r=47, stroke 6, заливка #008771 */ .wesp-gauge-ring--adm { width: 120px; height: 120px; } .wesp-gauge-fill--adm { stroke: #008771; } .wesp-gauge-caption { margin-top: 10px; font-size: 13px; line-height: 1.45; word-break: break-word; } .wesp-gauge-caption span[data-gauge-detail] { opacity: 0.75; font-weight: 500; } .wesp-gauge-caption--with-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; max-width: 100%; } .wesp-gauge-caption-text { text-align: left; } .wesp-gauge-history-btn { flex-shrink: 0; margin-left: 2px; } /* История нагрузки (раздел «Железо») */ .wesp-hardware-chart-hint { margin: 0 0 12px; font-size: 13px; opacity: 0.7; line-height: 1.4; } .wesp-hardware-chart-wrap { width: 100%; } .wesp-hardware-chart-svg { width: 100%; max-height: 260px; display: block; } .wesp-hardware-chart-legend { display: flex; flex-wrap: wrap; gap: 12px 20px; margin-top: 10px; font-size: 12px; } .wesp-hardware-chart-legend span { display: inline-flex; align-items: center; gap: 6px; } .wesp-hardware-chart-legend i { width: 10px; height: 3px; border-radius: 1px; display: inline-block; flex-shrink: 0; } /* Load average: подсказка */ #loadAvgPills { cursor: help; } /* Журнал действий: встроенный «терминал» (общий вид на всех темах) */ .wesp-admin-activity-terminal { margin-top: 20px; border-radius: 10px; overflow: hidden; border: 1px solid rgba(57, 212, 168, 0.28); background: linear-gradient(165deg, #0a0f0d 0%, #060807 48%, #0d1210 100%); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45), 0 12px 40px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(126, 231, 135, 0.06); font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; position: relative; } .wesp-admin-activity-terminal::after { content: ""; pointer-events: none; position: absolute; inset: 0; border-radius: inherit; background: repeating-linear-gradient( 0deg, transparent, transparent 2px, rgba(0, 0, 0, 0.11) 2px, rgba(0, 0, 0, 0.11) 3px ); opacity: 0.35; mix-blend-mode: multiply; } .wesp-admin-activity-terminal__chrome { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: rgba(0, 0, 0, 0.35); border-bottom: 1px solid rgba(57, 212, 168, 0.15); position: relative; z-index: 1; } .wesp-admin-activity-terminal__dots { flex-shrink: 0; width: 36px; height: 8px; position: relative; align-self: center; } /* Три точки в одном псевдоэлементе — иначе box-shadow вылезает за flex-ширину и наезжает на заголовок */ .wesp-admin-activity-terminal__dots::before { content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 95, 87, 0.85); box-shadow: 14px 0 0 rgba(255, 189, 46, 0.9), 28px 0 0 rgba(52, 199, 89, 0.85); } .wesp-admin-activity-terminal__title { flex: 1; min-width: 0; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: rgba(126, 231, 135, 0.88); text-shadow: 0 0 12px rgba(57, 212, 168, 0.35); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .wesp-admin-activity-terminal__badge { flex-shrink: 0; font-size: 10px; letter-spacing: 0.08em; color: rgba(126, 231, 135, 0.45); white-space: nowrap; } .wesp-admin-activity-terminal__body { position: relative; z-index: 1; max-height: 220px; overflow-y: auto; overflow-x: auto; padding: 10px 12px 12px; font-size: 11px; line-height: 1.55; scrollbar-color: rgba(57, 212, 168, 0.35) rgba(0, 0, 0, 0.3); } .wesp-admin-activity-line { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 8px; row-gap: 2px; white-space: pre-wrap; word-break: break-word; padding: 2px 0; border-left: 2px solid transparent; padding-left: 8px; margin-left: -2px; } .wesp-admin-activity-line--ok { color: #7ee787; text-shadow: 0 0 8px rgba(126, 231, 135, 0.22); border-left-color: rgba(57, 212, 168, 0.35); } .wesp-admin-activity-line--err { color: #ff7b72; text-shadow: 0 0 10px rgba(255, 80, 80, 0.25); border-left-color: rgba(255, 80, 80, 0.45); } .wesp-admin-activity-line--warn { color: #d4a72c; text-shadow: 0 0 8px rgba(212, 167, 44, 0.22); border-left-color: rgba(212, 167, 44, 0.45); } .wesp-admin-activity-line--empty { color: rgba(126, 231, 135, 0.35); font-style: italic; border-left-color: transparent; } .wesp-admin-activity-ts { flex-shrink: 0; color: rgba(126, 231, 135, 0.42); } .wesp-admin-activity-lvl { flex-shrink: 0; min-width: 2.25rem; font-weight: 600; letter-spacing: 0.04em; } .wesp-admin-activity-msg { flex: 1 1 140px; min-width: 0; word-break: break-word; } .wesp-admin-activity-line--ok .wesp-admin-activity-lvl { color: #39d4a8; } .wesp-admin-activity-line--err .wesp-admin-activity-lvl { color: #ff9491; } .wesp-admin-activity-line--warn .wesp-admin-activity-lvl { color: #e8b84d; } /* —— Дашборд: WESP / управление / трафик / IP —— */ .wesp-dash-service-row.ant-row { display: flex; flex-wrap: wrap; align-items: stretch; } .wesp-dash-service-row > .ant-col { display: flex; flex-direction: column; } .wesp-dash-service-row .wesp-dash-service-card { flex: 1 1 auto; width: 100%; min-height: 100%; display: flex; flex-direction: column; } .wesp-dash-service-card .ant-card-body { padding-top: 12px; flex: 1 1 auto; display: flex; flex-direction: column; } .wesp-dash-service-row .wesp-dash-manage-list { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; } .wesp-dash-manage-list { font-size: 13px; line-height: 1.4; } .wesp-dash-manage-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 16px; padding: 14px 0; border-bottom: 1px solid var(--border-faint, rgba(65, 85, 119, 0.35)); } .wesp-dash-manage-row:first-child { padding-top: 2px; } .wesp-dash-manage-row:last-child { border-bottom: none; padding-bottom: 2px; } .wesp-dash-manage-row--service { margin-top: 4px; padding-top: 16px; } .wesp-dash-manage-info { flex: 1 1 140px; min-width: 0; } .wesp-dash-manage-title { display: block; font-weight: 600; font-size: 13px; } .wesp-dash-manage-hint { display: block; margin-top: 4px; font-size: 12px; opacity: 0.65; line-height: 1.35; } .wesp-dash-manage-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 12px; flex-shrink: 0; } .wesp-dash-summary-block-title { font-size: 13px; font-weight: 600; margin-bottom: 10px; opacity: 0.85; } .wesp-dash-summary-generated { margin: 16px 8px 0; padding-top: 12px; border-top: 1px solid rgba(127, 127, 127, 0.2); font-size: 12px; opacity: 0.55; line-height: 1.4; } .wesp-admin-kv-key { width: 42%; max-width: 320px; opacity: 0.75; font-weight: 500; } .wesp-admin-mono-cell { font-size: 12px; word-break: break-all; } /* Списки настроек: основной текст, вторичная строка, значение или действия справа */ .wesp-adm-list { list-style: none; margin: 0; padding: 0; } .wesp-adm-list-wrap { overflow: hidden; } .wesp-adm-list-item { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 14px 20px; border-bottom: 1px solid rgba(127, 127, 127, 0.12); } .wesp-adm-list-item:last-child { border-bottom: none; } .wesp-adm-list-main { flex: 1; min-width: 0; } .wesp-adm-list-item--clickable .wesp-adm-list-main { cursor: pointer; } .wesp-adm-list-item--clickable .wesp-adm-list-main:hover .wesp-adm-list-title { color: var(--primary, #48816d); } .wesp-admin-user-modules-modal .ant-modal-footer { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px 16px; border-top: 1px solid rgba(127, 127, 127, 0.12); } .wesp-admin-user-modules-modal .ant-checkbox-wrapper { cursor: pointer; user-select: none; } .wesp-admin-user-modules-modal .ant-checkbox-input { cursor: pointer; } .wesp-adm-list-title { font-weight: 500; font-size: 14px; line-height: 1.45; } .wesp-adm-list-desc { margin-top: 4px; font-size: 12px; line-height: 1.45; opacity: 0.62; word-break: break-word; } .wesp-adm-list-extra { flex-shrink: 0; text-align: right; font-size: 13px; line-height: 1.45; max-width: min(440px, 46vw); word-break: break-word; } .wesp-adm-list-value { opacity: 0.92; } .wesp-adm-list-item.wesp-adm-list-section { display: block; padding: 10px 20px 8px; background: rgba(127, 127, 127, 0.07); border-bottom: 1px solid rgba(127, 127, 127, 0.12); } .wesp-adm-list-section-text { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.5; } .wesp-adm-list-item.wesp-adm-list-empty { display: block; padding: 20px 16px; border-bottom: none; } .wesp-adm-list-empty-text { text-align: center; opacity: 0.45; font-size: 13px; line-height: 1.45; } .wesp-adm-list-item.wesp-adm-list-loading .wesp-adm-list-empty-text { opacity: 0.72; display: inline-flex; align-items: center; justify-content: center; gap: 10px; } .wesp-inline-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(0, 0, 0, 0.12); border-top-color: var(--color-primary-100, #008771); border-radius: 50%; animation: wesp-inline-spin 0.75s linear infinite; flex-shrink: 0; } html.dark .wesp-inline-spinner, html[data-theme="ultra-dark"] .wesp-inline-spinner { border-color: rgba(255, 255, 255, 0.15); border-top-color: var(--color-primary-100, #3ad3ba); } @keyframes wesp-inline-spin { to { transform: rotate(360deg); } } .wesp-network-section--loading .wesp-network-settings-form { position: relative; } .wesp-network-section--loading .wesp-network-settings-form > :not(.wesp-network-form-loading) { opacity: 0.45; pointer-events: none; } .wesp-network-form-loading { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 10px 12px; margin-bottom: 12px; border-radius: 6px; font-size: 13px; color: rgba(0, 0, 0, 0.65); background: rgba(0, 135, 113, 0.08); border: 1px solid rgba(0, 135, 113, 0.18); } .wesp-network-form-loading[hidden] { display: none !important; } html.dark .wesp-network-form-loading, html[data-theme="ultra-dark"] .wesp-network-form-loading { color: rgba(255, 255, 255, 0.75); background: rgba(58, 211, 186, 0.08); border-color: rgba(58, 211, 186, 0.22); } .wesp-network-section--loading #netSettingsRefreshBtn, .wesp-network-section--loading #netEventsRefreshBtn { opacity: 0.65; pointer-events: none; } .wesp-adm-list-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; } .wesp-adm-list-error.wesp-sync-error-cell { display: inline-block; text-align: left; max-width: 360px; max-height: 7em; overflow: auto; } .wesp-adm-list-title--form { cursor: pointer; } .wesp-adm-list-item--multiline { flex-wrap: wrap; align-items: flex-start; } .wesp-adm-list-item--multiline .wesp-adm-list-main { flex: 1 1 100%; } .wesp-adm-list-item--multiline .wesp-adm-list-extra--full { flex: 1 1 100%; max-width: 100%; margin-top: 10px; text-align: left; } .wesp-adm-list-extra--field .ant-input.wesp-security-input, .wesp-adm-list-extra--field .ant-input { width: 100%; min-width: 200px; max-width: 400px; box-sizing: border-box; } .wesp-adm-list-extra--full .ant-input.wesp-security-input, .wesp-adm-list-extra--full textarea.ant-input { width: 100%; max-width: none; box-sizing: border-box; } .wesp-adm-list-extra--toggle { min-width: 52px; min-height: 44px; display: flex; align-items: center; justify-content: flex-end; padding-top: 0; } .wesp-security-switch { position: relative; display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; cursor: pointer; } .wesp-security-switch-ui { position: relative; display: inline-block; width: 44px; height: 24px; border-radius: 999px; background: rgba(127, 127, 127, 0.35); transition: background 0.2s ease; flex-shrink: 0; } .wesp-security-switch-ui::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.28); transition: transform 0.2s ease; } .wesp-security-checkbox { position: absolute; opacity: 0; width: 44px; height: 44px; margin: 0; cursor: pointer; inset: 0; z-index: 1; } .wesp-security-checkbox:checked + .wesp-security-switch-ui { background: var(--ant-primary-color, #177ddc); } .wesp-security-checkbox:checked + .wesp-security-switch-ui::after { transform: translateX(20px); } .wesp-security-checkbox:disabled + .wesp-security-switch-ui { opacity: 0.45; cursor: not-allowed; } .wesp-security-checkbox:disabled { cursor: not-allowed; } .wesp-security-checkbox:focus-visible + .wesp-security-switch-ui { outline: 2px solid var(--ant-primary-color, #177ddc); outline-offset: 2px; } .wesp-security-switch:has(.wesp-security-checkbox:disabled) { cursor: not-allowed; } .wesp-security-field-hint { margin: 8px 0 0; font-size: 12px; line-height: 1.45; color: #faad14; } .wesp-security-hint.wesp-sync-hint { margin: 0; padding: 14px 20px 12px; border-bottom: 1px solid rgba(127, 127, 127, 0.1); } .wesp-security-note-row { display: block !important; padding: 12px 20px !important; background: rgba(127, 127, 127, 0.06); } html[data-theme="light"] .wesp-security-note-row { background: rgba(0, 0, 0, 0.03); } .wesp-security-list-note { margin: 0; font-size: 12px; line-height: 1.45; opacity: 0.72; } .wesp-security-actions { margin: 0; padding: 16px 20px 20px; border-top: 1px solid rgba(127, 127, 127, 0.1); } html[data-theme="light"] .wesp-adm-list-item { border-bottom-color: rgba(0, 0, 0, 0.06); } html[data-theme="light"] .wesp-adm-list-item.wesp-adm-list-section { background: rgba(0, 0, 0, 0.03); } /* Таблицы админки: одинаковое скругление сверху и снизу */ .wesp-admin-data-table.ant-table-wrapper { --wesp-admin-table-radius: 20px; border-radius: var(--wesp-admin-table-radius); overflow: hidden; } .wesp-admin-data-table .ant-table, .wesp-admin-data-table table { border-radius: 0; } .wesp-admin-data-table .ant-table-content { border-radius: 0; } .wesp-admin-data-table .ant-table-thead > tr > th, .wesp-admin-data-table .ant-table-tbody > tr > td { border-radius: 0; } .wesp-admin-data-table .ant-table-thead > tr > th { font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.03em; opacity: 0.75; background: rgba(127, 127, 127, 0.07); border-bottom: 1px solid rgba(127, 127, 127, 0.22); padding: 12px 16px; } .wesp-admin-data-table .ant-table-tbody > tr.wesp-admin-table-data-row > td { padding: 11px 16px; vertical-align: top; line-height: 1.45; border-bottom: 1px solid rgba(127, 127, 127, 0.12); } .wesp-admin-data-table .ant-table-tbody > tr.wesp-admin-table-data-row:last-child > td { border-bottom: none; } .wesp-admin-data-table .ant-table-tbody > tr.wesp-admin-table-section > td { border-radius: 0; padding: 14px 16px 8px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.5; background: rgba(127, 127, 127, 0.06); border-top: 1px solid rgba(127, 127, 127, 0.18); border-bottom: 1px solid rgba(127, 127, 127, 0.1); } html[data-theme="light"] .wesp-admin-data-table .ant-table-thead > tr > th { background: rgba(0, 0, 0, 0.04); } html[data-theme="light"] .wesp-admin-data-table .ant-table-tbody > tr.wesp-admin-table-section > td { background: rgba(0, 0, 0, 0.03); } .wesp-sync-hint { margin: 0 0 14px; font-size: 13px; line-height: 1.45; opacity: 0.72; } .wesp-sync-hint--ok { opacity: 1; color: #389e0d; } .wesp-sync-hint--error { opacity: 1; color: #cf1322; } html[data-theme="dark"] .wesp-sync-hint--ok { color: #73d13d; } html[data-theme="dark"] .wesp-sync-hint--error { color: #ff7875; } .wesp-sync-url-combo { display: flex; flex-wrap: wrap; align-items: stretch; gap: 8px; max-width: 640px; } .wesp-sync-scheme-select { flex: 0 0 auto; min-width: 7.5rem; max-width: 9rem; } .wesp-sync-host-input { flex: 1 1 200px; min-width: 0; } .wesp-sync-errors-hint { margin: 0 0 12px; padding: 0 16px; } .wesp-sync-error-cell { max-width: 28rem; word-break: break-word; white-space: pre-wrap; font-size: 12px; line-height: 1.35; color: var(--wesp-danger, #ff7875); } html[data-theme="light"] .wesp-sync-error-cell { color: #cf1322; } .wesp-sync-settings-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px 20px; } .wesp-sync-field { display: flex; flex-direction: column; gap: 6px; } .wesp-sync-field--grow { flex: 1 1 220px; min-width: 200px; } .wesp-sync-field--actions { flex-shrink: 0; } .wesp-sync-label { font-size: 12px; opacity: 0.65; } .wesp-sync-client-actions { white-space: nowrap; } .wesp-sync-client-actions .ant-btn { margin-right: 8px; } .wesp-sync-client-actions .ant-btn:last-child { margin-right: 0; } .wesp-diagnostics-hint.wesp-sync-hint { margin: 0; padding: 14px 20px 12px; border-bottom: 1px solid rgba(127, 127, 127, 0.1); } .wesp-diagnostics-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; } .wesp-diagnostics-targets { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; } .wesp-diagnostics-target-row { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr) minmax(140px, auto); gap: 8px; align-items: center; } .wesp-diagnostics-target-row .wesp-adm-list-actions { justify-content: flex-start; flex-wrap: nowrap; min-width: 0; } .wesp-diagnostics-target-row .wesp-adm-list-actions .ant-input { flex: 1 1 auto; min-width: 0; } .wesp-diagnostics-target-row .ant-btn { flex: 0 0 auto; min-width: 34px; } @media (max-width: 720px) { .wesp-diagnostics-target-row { grid-template-columns: 1fr; } .wesp-diagnostics-target-row .wesp-adm-list-actions { flex-wrap: wrap; } } .wesp-diagnostics-path { margin: 0; } .wesp-diag-summary-head { align-items: flex-start; } .wesp-diag-summary-head-sub { margin: 6px 0 0; font-size: 12px; line-height: 1.45; max-width: 52em; } .wesp-diagnostics-results-wrap { margin-top: 10px; } .wesp-diag-ok { color: var(--wesp-success, #52c41a); font-weight: 600; } .wesp-diag-bad { color: var(--wesp-danger, #ff7875); font-weight: 600; } .wesp-dash-wesp-meta { display: flex; flex-direction: column; gap: 10px; font-size: 13px; } .wesp-dash-wesp-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; line-height: 1.4; } .wesp-dash-wesp-label { opacity: 0.65; flex-shrink: 0; } .wesp-dash-wesp-value { font-weight: 500; text-align: right; } .wesp-dash-status { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; } /* В antd у .ant-card-extra цвет rgba(0,0,0,.65) — на тёмной шапке карточки текст «пропадает» */ html.dark .wesp-dash-service-card .ant-card-extra { color: var(--dark-color-text-primary, rgba(255, 255, 255, 0.85)) !important; } .wesp-dash-status #wespRuntimeStatus { color: inherit; } .wesp-status-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; box-sizing: border-box; transform: translateZ(0); } /* Пульс статуса (.xray-running-animation), keyframes в custom.min.css */ .wesp-status-dot--ok { background: var(--color-primary-100, #008771); border: 1px solid rgba(0, 0, 0, 0.45); box-shadow: none; animation: runningAnimation 1.2s linear infinite; } .wesp-status-dot--warn { background: #d4b106; border: 1px solid rgba(0, 0, 0, 0.35); box-shadow: none; } @media (prefers-reduced-motion: reduce) { .wesp-status-dot--ok { animation: none; } } .wesp-traffic-card .ant-card-body { padding: 16px 20px 20px; } .wesp-traffic-two-col { display: flex; flex-wrap: wrap; gap: 16px 24px; } .wesp-traffic-col { flex: 1 1 160px; min-width: 0; } .wesp-traffic-label { font-size: 13px; opacity: 0.65; margin-bottom: 8px; } .wesp-traffic-value { font-size: 18px; font-weight: 600; letter-spacing: 0.02em; } .wesp-traffic-arrow, .wesp-traffic-icon { opacity: 0.75; margin-right: 4px; } .wesp-dash-meta-pills { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; } /* Только иконка (ant-btn-icon-only), глаз / глаз с перечёркиванием */ .wesp-ip-reveal-btn.ant-btn-icon-only { width: 28px; min-width: 28px; height: 28px; padding: 0; line-height: 1; } .wesp-ip-reveal-btn__icon { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; } .wesp-ip-reveal-btn__icon svg { width: 14px; height: 14px; display: block; } .wesp-ip-reveal-btn .wesp-ip-reveal-btn__icon--hide { display: none; } .wesp-ip-reveal-btn.is-ip-hidden .wesp-ip-reveal-btn__icon--show { display: none; } .wesp-ip-reveal-btn.is-ip-hidden .wesp-ip-reveal-btn__icon--hide { display: inline-flex; } .wesp-server-ip-list { font-size: 13px; line-height: 1.6; } .wesp-ip-line { padding: 4px 0; border-bottom: 1px solid var(--border-faint, rgba(65, 85, 119, 0.35)); } .wesp-ip-line:last-child { border-bottom: none; } .wesp-ip-if { opacity: 0.65; margin-right: 8px; font-size: 12px; } .wesp-ip-fam { opacity: 0.5; font-size: 12px; margin-right: 8px; } .wesp-ip-addr { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; } .wesp-ip-masked .wesp-ip-addr { filter: blur(7px); user-select: none; } /* Модальное окно журнала — разметка ant-modal-* */ .wesp-admin-modal { position: fixed; inset: 0; z-index: 10000; } .wesp-admin-modal[hidden] { display: none !important; } .wesp-admin-modal .ant-modal-mask { z-index: 0; } .wesp-admin-modal .ant-modal-wrap { z-index: 1; } .wesp-admin-modal .ant-modal-close-x { display: flex; align-items: center; justify-content: center; } .wesp-admin-modal .ant-modal-close-x svg { flex-shrink: 0; } /* Размер и прокрутка контента журнала (поверх стилей antd) */ .wesp-admin-modal .wesp-admin-log-modal.ant-modal { top: 48px; width: min(920px, calc(100vw - 32px)) !important; max-width: calc(100vw - 24px); padding-bottom: 24px; } .wesp-admin-modal .ant-modal-content { max-height: min(85vh, 720px); display: flex; flex-direction: column; overflow: hidden; } .wesp-admin-modal .ant-modal-body { flex: 1 1 auto; min-height: 0; overflow: auto !important; display: flex; flex-direction: column; } .wesp-admin-modal-pre { margin: 0; flex: 1 1 auto; min-height: 12rem; white-space: pre-wrap; word-break: break-word; font-size: 12px; line-height: 1.5; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; padding: 12px 14px; border-radius: 0.5rem; background: #fafafa; border: 1px solid #e8e8e8; color: rgba(0, 0, 0, 0.85); } html.dark .wesp-admin-modal-pre, html[data-theme="ultra-dark"] .wesp-admin-modal-pre { background: var(--dark-color-surface-200, #222d42); border-color: var(--dark-color-stroke, #2c3950); color: var(--dark-color-text-primary, rgba(255, 255, 255, 0.85)); } @media (max-width: 576px) { .wesp-admin-modal .wesp-admin-log-modal.ant-modal { top: 16px; width: calc(100vw - 16px) !important; max-width: calc(100vw - 16px); } } /* Трассировка по списку IP (диагностика) */ .wesp-admin-modal .wesp-admin-traceroute-modal.ant-modal { top: 32px; width: min(960px, calc(100vw - 24px)) !important; max-width: calc(100vw - 16px); padding-bottom: 24px; } .wesp-admin-traceroute-modal-body { display: flex; flex-direction: column; gap: 0; min-height: 0; } .wesp-admin-traceroute-results { margin-top: 16px; max-height: min(50vh, 420px); overflow: auto; border-radius: 0.5rem; border: 1px solid #e8e8e8; background: #fafafa; padding: 10px 12px; font-size: 12px; } html.dark .wesp-admin-traceroute-results, html[data-theme="ultra-dark"] .wesp-admin-traceroute-results { border-color: var(--dark-color-stroke, #2c3950); background: var(--dark-color-surface-200, #1a2332); } .wesp-admin-traceroute-target { margin-bottom: 18px; padding-bottom: 14px; border-bottom: 1px solid rgba(0, 0, 0, 0.06); } html.dark .wesp-admin-traceroute-target, html[data-theme="ultra-dark"] .wesp-admin-traceroute-target { border-bottom-color: rgba(255, 255, 255, 0.08); } .wesp-admin-traceroute-target:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } .wesp-admin-traceroute-pre { margin: 8px 0 0; padding: 8px 10px; border-radius: 0.375rem; background: rgba(0, 0, 0, 0.04); white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; max-height: 200px; overflow: auto; } html.dark .wesp-admin-traceroute-pre, html[data-theme="ultra-dark"] .wesp-admin-traceroute-pre { background: rgba(0, 0, 0, 0.25); } .wesp-admin-code-inline { font-family: ui-monospace, monospace; font-size: 0.9em; padding: 0 0.25em; border-radius: 0.25rem; background: rgba(0, 0, 0, 0.06); } html.dark .wesp-admin-code-inline, html[data-theme="ultra-dark"] .wesp-admin-code-inline { background: rgba(255, 255, 255, 0.08); } /* Локальный SQL-редактор (sql.js) — шире журнала */ .wesp-admin-modal .wesp-admin-sqlite-modal.ant-modal { top: 24px; width: min(1100px, calc(100vw - 24px)) !important; max-width: calc(100vw - 16px); padding-bottom: 24px; } .wesp-admin-sqlite-modal-body { display: flex; flex-direction: column; gap: 10px; } /* Модалка «База на сервере»: тело окна сжимается, строки таблицы прокручиваются внутри сетки */ #adminSqliteModal .ant-modal-content { max-height: min(92vh, 920px) !important; display: flex !important; flex-direction: column; } #adminSqliteModal .ant-modal-header { flex-shrink: 0; } #adminSqliteModal .ant-modal-body.wesp-db-browser-body { flex: 1 1 auto; min-height: 0; overflow: hidden !important; display: flex; flex-direction: column; } #adminSqliteModal .wesp-db-browser-body > .wesp-db-browser__intro, #adminSqliteModal .wesp-db-browser-body > .wesp-db-browser__toolbar, #adminSqliteModal .wesp-db-browser-body > .wesp-sqlite-editor__error { flex-shrink: 0; } .wesp-db-browser__intro { font-size: 13px; opacity: 0.88; margin: 0; line-height: 1.45; } .wesp-db-browser__toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 12px; margin-bottom: 4px; } .wesp-db-browser__muted { font-size: 13px; opacity: 0.72; margin: 0; } .wesp-db-browser-layout { display: flex; gap: 14px; align-items: stretch; flex: 1 1 auto; min-height: 0; overflow: hidden; } .wesp-db-tree-panel { flex: 0 0 min(240px, 34%); max-width: 280px; border: 1px solid #e8e8e8; border-radius: 6px; padding: 10px 8px; background: #fafafa; overflow: auto; min-height: 0; align-self: stretch; } html.dark .wesp-db-tree-panel, html[data-theme="ultra-dark"] .wesp-db-tree-panel { background: var(--dark-color-surface-200, #1a2332); border-color: var(--dark-color-stroke, #2c3950); } .wesp-db-tree-panel-title { font-size: 12px; font-weight: 600; opacity: 0.75; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.02em; } .wesp-db-tree { list-style: none; margin: 0; padding: 0; } .wesp-db-tree-node { margin: 2px 0; } .wesp-db-tree-caret { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; margin-right: 2px; padding: 0; border: none; background: transparent; cursor: pointer; color: inherit; vertical-align: middle; border-radius: 4px; } .wesp-db-tree-caret:hover { background: rgba(0, 0, 0, 0.06); } html.dark .wesp-db-tree-caret:hover, html[data-theme="ultra-dark"] .wesp-db-tree-caret:hover { background: rgba(255, 255, 255, 0.08); } .wesp-db-tree-caret-icon { display: inline-block; font-size: 10px; transition: transform 0.2s ease; } .wesp-db-tree-node.is-open > .wesp-db-tree-caret .wesp-db-tree-caret-icon { transform: rotate(90deg); } .wesp-db-tree-folder { font-weight: 600; font-size: 13px; } .wesp-db-tree-children { display: none; list-style: none; margin: 4px 0 6px 0; padding: 0 0 0 14px; border-left: 1px solid rgba(0, 0, 0, 0.08); } html.dark .wesp-db-tree-children, html[data-theme="ultra-dark"] .wesp-db-tree-children { border-left-color: rgba(255, 255, 255, 0.12); } .wesp-db-tree-node.is-open > .wesp-db-tree-children { display: flex; flex-direction: column; gap: 8px; } .wesp-db-tree-leaf { margin: 0; } .wesp-db-tree-table { width: 100%; text-align: left; justify-content: flex-start; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; } .wesp-db-tree-table.is-active { border-color: #1890ff; color: #1890ff; } .wesp-db-grid-panel { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 8px; } .wesp-db-grid-meta { font-size: 12px; opacity: 0.85; line-height: 1.4; flex-shrink: 0; } .wesp-db-pager { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; flex-shrink: 0; } .wesp-db-grid-wrap { flex: 1 1 auto; min-height: 0; overflow: auto; overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid #e8e8e8; border-radius: 6px; background: #fff; } html.dark .wesp-db-grid-wrap, html[data-theme="ultra-dark"] .wesp-db-grid-wrap { background: var(--dark-color-background, #141414); border-color: var(--dark-color-stroke, #2c3950); } .wesp-db-grid-table { /* Шире контейнера — горизонтальный скролл у .wesp-db-grid-wrap, колонки не сжимают UUID/даты */ width: max-content; min-width: 100%; table-layout: auto; border-collapse: collapse; font-size: 12px; } .wesp-db-grid-table th, .wesp-db-grid-table td { border-bottom: 1px solid #f0f0f0; padding: 8px 10px; text-align: left; vertical-align: middle; } .wesp-db-grid-table td:not(:last-child) { min-width: 12rem; } .wesp-db-grid-table td:last-child { padding-left: 12px; width: 1%; white-space: nowrap; min-width: unset; } .wesp-db-grid-actions-col { white-space: nowrap; } .wesp-db-row-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 10px; } .wesp-db-grid-table .wesp-db-row-save, .wesp-db-grid-table .wesp-db-row-delete { margin: 0; } html.dark .wesp-db-grid-table th, html.dark .wesp-db-grid-table td, html[data-theme="ultra-dark"] .wesp-db-grid-table th, html[data-theme="ultra-dark"] .wesp-db-grid-table td { border-bottom-color: #2c3950; } .wesp-db-grid-table th { position: sticky; top: 0; background: #fafafa; z-index: 1; font-weight: 600; } html.dark .wesp-db-grid-table th, html[data-theme="ultra-dark"] .wesp-db-grid-table th { background: #1f2a3d; } .wesp-db-grid-wrap .wesp-db-cell.ant-input { box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; /* Запас под UUID / ISO-дату, если нет field-sizing */ min-width: 22rem; width: 36ch; max-width: min(48rem, 92vw); overflow-x: auto; text-overflow: clip; } @supports (field-sizing: content) { .wesp-db-grid-wrap .wesp-db-cell.ant-input { field-sizing: content; width: auto !important; min-width: 12ch; max-width: min(56rem, 92vw); overflow-x: visible; } } .wesp-db-cell-readonly { opacity: 0.65; font-size: 12px; white-space: nowrap; } @media (max-width: 768px) { .wesp-db-browser-layout { flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; } .wesp-db-tree-panel { flex: 0 0 auto; max-width: none; width: 100%; max-height: min(220px, 32vh); min-height: 0; } .wesp-db-grid-panel { flex: 1 1 auto; min-height: 0; } } .wesp-sqlite-editor__error { color: #cf1322; font-size: 13px; margin: 8px 0 0; min-height: 1.2em; } html.dark .wesp-sqlite-editor__error, html[data-theme="ultra-dark"] .wesp-sqlite-editor__error { color: #ff7875; } @media (max-width: 576px) { .wesp-admin-modal .wesp-admin-sqlite-modal.ant-modal { top: 8px; width: calc(100vw - 12px) !important; } } /* Открытие модалки журнала */ @keyframes wesp-admin-modal-mask-in { from { opacity: 0; } to { opacity: 1; } } @keyframes wesp-admin-modal-content-in { from { opacity: 0; transform: scale(0.94) translateY(18px); } to { opacity: 1; transform: scale(1) translateY(0); } } .wesp-admin-modal:not([hidden]) .ant-modal-mask { animation: wesp-admin-modal-mask-in 0.35s ease both; } .wesp-admin-modal:not([hidden]) .ant-modal-content { animation: wesp-admin-modal-content-in 0.4s cubic-bezier(0.22, 1, 0.36, 1) both; } @media (prefers-reduced-motion: reduce) { .wesp-admin-modal:not([hidden]) .ant-modal-mask, .wesp-admin-modal:not([hidden]) .ant-modal-content { animation: none !important; } } /* JSON / pre внутри карточек */ .wesp-admin-pre { margin: 0; white-space: pre-wrap; font-size: 13px; line-height: 1.5; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; } /* Кнопки действий в таблице пользователей */ .wesp-user-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 10px; max-width: 100%; } .wesp-user-actions .ant-btn { margin: 0; } @media (max-width: 768px) { .wesp-admin-content-topbar { justify-content: flex-start; } #app.ant-layout-has-sider { flex-direction: column; } .wesp-admin-sider.ant-layout-sider, .wesp-admin-sider.ant-layout-sider.ant-layout-sider-collapsed { flex: 0 0 auto !important; max-width: none !important; min-width: 0 !important; width: 100% !important; height: auto !important; } .wesp-admin-sider .ant-layout-sider-trigger { display: none; } .wesp-admin-sider.ant-layout-sider-has-trigger { padding-bottom: 0 !important; } .wesp-admin-sider.ant-layout-sider-collapsed .wesp-admin-brand { max-height: 5.5rem !important; opacity: 1 !important; padding: 16px 12px 14px !important; margin: 0 !important; border-bottom-color: var(--border-faint, rgba(65, 85, 119, 0.5)) !important; pointer-events: auto !important; overflow: hidden !important; } .wesp-admin-sider.ant-layout-sider-collapsed .wesp-admin-brand-title { transform: none !important; opacity: 1 !important; } .wesp-admin-sider.ant-layout-sider-collapsed .wesp-menu-label { max-width: 16rem !important; opacity: 1 !important; margin: 0 !important; padding: 0 !important; overflow: visible !important; pointer-events: auto !important; } .wesp-admin-sider.ant-layout-sider-collapsed .ant-menu-item { justify-content: flex-start !important; gap: 10px; padding-left: 24px !important; padding-right: 24px !important; } } /* Первая синхронизация (клиент): прогресс в админке */ .wesp-sync-progress-bar { height: 8px; border-radius: 4px; background: rgba(0, 0, 0, 0.08); overflow: hidden; } .wesp-sync-progress-fill { height: 100%; border-radius: 4px; background: linear-gradient(90deg, #1890ff, #52c41a); transition: width 0.35s ease; max-width: 100%; } /* Sync diagnostics (admin) */ .wesp-sync-diag-subcard { border-top: 1px solid var(--border-faint, rgba(65, 85, 119, 0.35)); padding: 12px 16px; } .wesp-sync-diag-subtitle { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; margin-bottom: 8px; } .wesp-sync-diag-table-wrap { overflow-x: auto; margin-top: 8px; } .wesp-sync-diag-table-wrap table { width: 100%; border-collapse: collapse; font-size: 12px; } .wesp-sync-diag-table-wrap th, .wesp-sync-diag-table-wrap td { border: 1px solid var(--border-faint, rgba(65, 85, 119, 0.35)); padding: 6px 8px; text-align: left; vertical-align: top; } .wesp-sync-diag-table-wrap th { background: rgba(0, 0, 0, 0.04); } html.dark .wesp-sync-diag-table-wrap th { background: rgba(255, 255, 255, 0.06); } /* Локальный ассистент (LLM) — админка */ .wesp-assistant-hint-list { margin: 0 0 12px 0; padding-left: 1.25rem; font-size: 13px; line-height: 1.45; opacity: 0.92; } .wesp-assistant-hint-list li { margin-bottom: 6px; } .wesp-assistant-subtitle { font-size: 13px; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; opacity: 0.8; margin-bottom: 8px; padding-top: 4px; border-top: 1px solid var(--border-faint, rgba(65, 85, 119, 0.35)); } .wesp-admin-section[data-section-content="assistant"] .wesp-assistant-subtitle:first-of-type { border-top: none; padding-top: 0; } .wesp-assistant-llm-log .wesp-admin-activity-terminal__body { max-height: 200px; } .wesp-assistant-chat-log { min-height: 200px; max-height: 360px; overflow: auto; margin-bottom: 8px; white-space: pre-wrap; } .wesp-assistant-tool-trace { font-size: 12px; opacity: 0.95; } .wesp-assistant-output-pre { max-height: 320px; overflow: auto; white-space: pre-wrap; } .wesp-assistant-pending { font-style: italic; opacity: 0.88; } .wesp-assistant-msg--pending { border-left: 3px solid rgba(24, 144, 255, 0.55); } .wesp-admin-section[data-section-content="assistant"] kbd { display: inline-block; padding: 1px 6px; font-size: 11px; border-radius: 4px; border: 1px solid var(--border-faint, rgba(65, 85, 119, 0.45)); background: rgba(0, 0, 0, 0.06); } html.dark .wesp-admin-section[data-section-content="assistant"] kbd { background: rgba(255, 255, 255, 0.08); } /* Железо: симуляция весов */ .wesp-hw-sim-head { margin-bottom: 4px; } .wesp-hw-sim-switch { display: inline-flex; align-items: center; gap: 12px; cursor: pointer; user-select: none; } .wesp-hw-sim-switch input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; } .wesp-hw-sim-switch-ui { flex-shrink: 0; width: 44px; height: 24px; border-radius: 12px; background: rgba(127, 127, 127, 0.35); position: relative; transition: background 0.2s ease; } .wesp-hw-sim-switch-ui::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25); transition: transform 0.2s ease; } .wesp-hw-sim-switch input:checked + .wesp-hw-sim-switch-ui { background: var(--color-primary-100, #008771); } .wesp-hw-sim-switch input:checked + .wesp-hw-sim-switch-ui::after { transform: translateX(20px); } .wesp-hw-sim-switch input:focus-visible + .wesp-hw-sim-switch-ui { outline: 2px solid var(--color-primary-100, #008771); outline-offset: 2px; } .wesp-hw-sim-status { font-size: 13px; line-height: 1.4; } .wesp-hw-sim-panel { margin-top: 16px; padding-top: 16px; border-top: 1px solid rgba(127, 127, 127, 0.2); } .wesp-hw-sim-hint { margin: 0 0 12px; } .wesp-hw-sim-hint strong { font-variant-numeric: tabular-nums; } .wesp-hw-sim-weight-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px; } .wesp-hw-sim-input { width: 5.5rem; text-align: center; font-variant-numeric: tabular-nums; } .wesp-hw-sim-unit { font-size: 13px; opacity: 0.7; } .wesp-hw-sim-slider { display: block; width: 100%; max-width: 480px; margin-top: 6px; accent-color: var(--color-primary-100, #008771); cursor: pointer; } html[data-theme="light"] .wesp-hw-sim-switch-ui { background: rgba(0, 0, 0, 0.15); } .wesp-icon-btn { display: inline-flex; align-items: center; justify-content: center; min-width: 32px; padding: 4px 8px; } .wesp-icon-btn svg { display: block; } .ant-card-head-wrapper.wesp-diag-summary-head .wesp-icon-btn { flex-shrink: 0; margin-left: auto; color: rgba(255, 255, 255, 0.65); } html[data-theme="light"] .ant-card-head-wrapper.wesp-diag-summary-head .wesp-icon-btn { color: rgba(0, 0, 0, 0.55); } .wesp-icon-btn:hover { color: var(--wesp-danger, #ff7875); border-color: rgba(255, 120, 117, 0.45); }