Files
portal/liderra_v8_handoff/concepts/v8_admin.html
T
Дмитрий 887abf444e rebrand(v8.5→Лидерра): дизайн-handoff Платона v8 Forest + Лидпоток→Лидерра
Получен handoff-пакет liderra_v8_handoff/ от дизайнера Платона
(kpd9363@gmail.com) от 07.05.2026 — v8 Forest. Заказчик 08.05 решил
применить только в части дизайна, имени, логотипа. Функционал, состав
страниц и правила (CTO-11, click-wrap, SSO break-glass, 14 статусов
воронки) — без изменений (источник — ТЗ v8.5/schema v8.5).

Что сделано:

- Массовая замена Лидпоток→Лидерра (с учётом падежей: Лидерры/Лидерре)
  в 33 файлах (449 вхождений) — все .md/.sql/.json/.toml/.yml/.txt/.html,
  кроме исторических упоминаний внутри liderra_v8_handoff/
- Удалён docs/brandbook.md v1.1 — заменён на BRANDBOOK_v2.md из handoff
- Скопированы 13 концептов liderra_v8_handoff/concepts/v8_*.html в
  web/v8/. Удалены старые web/01-login.html, 02-dashboard.html,
  03-deals.html, index.html (палитра v1.1 deprecated)
- CLAUDE.md v1.0→v1.1: §0 (BRANDBOOK_v2 + DEVELOPER_HANDOFF в источниках),
  §2 (палитра Forest, Inter+JBM, Lucide), §5 п.6 (anti-pattern Inter
  снят — в Forest Inter наш основной шрифт), §6 (13 концептов в web/v8/)
- Реестр Открытые_вопросы_v8_3.md v1.12→v1.13: добавлена запись о
  ребрендинге + 4 точечных расхождений handoff vs ТЗ (статусы воронки,
  click-wrap чекбоксы, SSO fallback, axe violations)
- package.json/package-lock.json: name lidpotok→liderra

4 расхождения handoff vs ТЗ (НЕ применены, источник истины — ТЗ/schema):

1. 14 «обобщённых» статусов в BRANDBOOK_v2 §3.6 ≠ 14 slug'ов в
   schema.sql:2076 (совпадает 2 из 14: «Переговоры», «Оплачено»).
   Источник — schema/ТЗ §6.4 (реселлерская модель из аудита crm.bp-gr.ru,
   6 системных + 8 настраиваемых статусов).
2. 3-й click-wrap в v8_login.html («маркетинг-опционально») ≠ ТЗ §1.5/§4.1
   («согласие на ПДн», обязательное, OPEN-Ж-3).
3. SSO в v8_admin.html («локальный 2FA fallback») ≠ ТЗ OPEN-И-13
   (break-glass super_admin, локальный 2FA выключен).
4. Заявление «axe-core 4.10.2 — 0 violations» в README handoff — локально
   Pa11y 9.1.1 + axe нашёл 81 violation на 10/13 HTML (преимущественно
   color-contrast на декоративных separator'ах с --ink-disabled).
   Чисто: settings/errors/palette_options.

Что НЕ включено в коммит:
- лендинг/TZ_landing_v1_0.md — untracked, не моя работа в этой сессии
- .tmp/ — gitignored

Что осталось (для следующих сессий):
- Возможное переименование GitHub-репо CoralMinister/lidpotok → liderra
  (отдельное решение заказчика)
- Опционально: обратная связь Платону по 4 расхождениям handoff vs ТЗ

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:11:58 +03:00

545 lines
48 KiB
HTML
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.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>v8 · Админка SaaS — Лидерра (Forest)</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600;14..32,700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
:root {
--bg:#F6F3EC; --surface:#FFFDFA; --sunken:#F0EDE4;
--hairline:#D9D5CD; --hairline-soft:#E8E3D6;
--ink:#081319; --ink-2:#343C41; --ink-3:#66635C; --ink-disabled:#92907B;
--accent:#0F6E56; --accent-tint:#E1EEEA; --accent-deep:#084635;
--side-bg:#012019; --side-text:#B1C2BD; --side-text-2:#7A8C87;
--side-active:#13382F; --side-icon:#5C7A72; --side-icon-act:#32C8A9;
--side-hover:#0A2A22; --side-border:#1A3A30;
--st-paid:#007EB8; --st-quote:#008A4D; --st-call:#9A6700; --st-new:#B94837; --st-fail:#6C60C4;
--r-xs:4px; --r-sm:6px; --r-md:10px; --r-lg:14px;
--font-ui:'Inter',system-ui,sans-serif;
--font-mono:'JetBrains Mono',ui-monospace,monospace;
--imp-red: #B94837;
}
body { background:var(--bg); color:var(--ink); font-family:var(--font-ui); font-feature-settings:'cv11','ss01'; -webkit-font-smoothing:antialiased; font-variation-settings:'opsz' 14; min-height:100vh; }
button { font-family:inherit; }
a { color:inherit; text-decoration:none; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible {
outline:2px solid var(--accent); outline-offset:2px; border-radius:var(--r-sm);
}
/* Review-only state switcher */
.review-bar { position:sticky; top:0; z-index:100; background:var(--side-bg); padding:10px 16px; display:flex; align-items:center; gap:14px; border-bottom:1px solid #1A3A30; flex-wrap:wrap; }
.review-bar .label { font-size:11px; font-weight:600; letter-spacing:0.06em; color:#7A8C87; font-family:var(--font-mono); }
.review-bar .tabs { display:flex; gap:2px; flex-wrap:wrap; }
.review-bar .tab { height:26px; padding:0 12px; border:none; background:transparent; color:#B1C2BD; font-family:inherit; font-size:12px; font-weight:500; cursor:pointer; border-radius:4px; }
.review-bar .tab:hover { background:#0A2A22; color:#fff; }
.review-bar .tab.active { background:#fff; color:#012019; }
/* Impersonation banner — only visible on tenant-card-imp */
.imp-banner {
background: var(--imp-red); color: #fff;
padding: 9px 24px;
display: flex; align-items: center; gap: 12px; justify-content: space-between;
font-size: 12.5px;
position: sticky; top: 47px; z-index: 90;
}
.imp-banner svg { width: 14px; height: 14px; }
.imp-banner strong { font-weight: 600; }
.imp-banner button {
height: 24px; padding: 0 10px;
border: 1px solid rgba(255,255,255,0.30);
background: rgba(255,255,255,0.10);
color: #fff;
font-family: inherit; font-size: 11px; font-weight: 500;
border-radius: 4px; cursor: pointer;
}
.imp-banner button:hover { background: rgba(255,255,255,0.18); }
/* App shell — same Forest with admin variation */
.app { display:grid; grid-template-columns:232px 1fr; min-height:calc(100vh - 47px); }
.side { background:var(--side-bg); border-right:1px solid var(--side-border); padding:18px 12px 24px; position:sticky; top:47px; height:calc(100vh - 47px); overflow-y:auto; color:var(--side-text); }
.brand { display:flex; align-items:center; gap:10px; padding:6px 8px 4px; font-weight:600; font-size:14.5px; letter-spacing:-0.01em; font-variation-settings:'opsz' 18; color:#FFF; }
.brand-mark { width:22px; height:22px; border-radius:var(--r-xs); background:#FFF; display:inline-flex; align-items:center; justify-content:center; flex-shrink:0; overflow:hidden; }
.brand-mark svg { width:100%; height:100%; display:block; }
.brand-dot { color:var(--side-icon-act); }
.brand-sub { font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.08em; color: var(--side-icon-act); padding: 0 8px 16px; font-weight: 600; }
.nav { display:flex; flex-direction:column; gap:1px; }
.nav-eyebrow { font-size:11px; font-weight:500; letter-spacing:0.01em; color:var(--side-text-2); padding:14px 10px 6px; }
.nav-item { display:flex; align-items:center; gap:10px; height:32px; padding:0 10px; border-radius:var(--r-sm); font-size:13px; color:var(--side-text); cursor: pointer; }
.nav-item:hover { background:var(--side-hover); color:#FFF; }
.nav-item.active { background:var(--side-active); color:#FFF; font-weight:500; }
.nav-item.active .nav-icon { color:var(--side-icon-act); }
.nav-icon { width:15px; height:15px; flex-shrink:0; color:var(--side-icon); stroke-width:1.6; }
.nav-item:hover .nav-icon { color:#FFF; }
.nav-text { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.nav-count { font-family:var(--font-mono); font-size:10.5px; font-weight:500; font-feature-settings:'tnum'; background:rgba(255,255,255,0.10); color:var(--side-text); padding:2px 6px; border-radius:4px; }
.main { display:flex; flex-direction:column; min-width:0; }
.topbar { height:48px; border-bottom:1px solid var(--hairline); background:var(--surface); padding:0 24px; display:flex; align-items:center; gap:12px; position:sticky; top:47px; z-index:50; }
.crumb { font-size:12.5px; color:var(--ink-3); display:flex; align-items:center; gap:8px; }
.crumb strong { color:var(--ink); font-weight:500; }
.crumb svg { width:11px; height:11px; color:var(--ink-3); opacity:0.5; }
.crumb a { cursor:pointer; }
.crumb a:hover { color:var(--ink); }
.topbar-spacer { flex:1; }
.user-chip { display:inline-flex; align-items:center; gap:8px; height:30px; padding:0 10px 0 4px; border-radius:100px; border:1px solid var(--hairline); background:var(--surface); }
.user-chip .ava { width:22px; height:22px; border-radius:50%; background:var(--ink); color:#fff; display:inline-flex; align-items:center; justify-content:center; font-size:9.5px; font-weight:600; }
.user-chip .uname { font-size:12px; color:var(--ink); font-weight:500; }
.content { padding:24px 28px 60px; flex:1; max-width: 1700px; margin: 0 auto; width:100%; }
.page-h { display:flex; align-items:flex-end; justify-content:space-between; margin-bottom:18px; gap:16px; flex-wrap: wrap; }
.page-title { font-size:26px; font-weight:600; font-variation-settings:'opsz' 26; letter-spacing:-0.02em; line-height:1.1; margin:0 0 6px; }
.page-meta { font-size:12.5px; color:var(--ink-3); display:flex; gap:14px; align-items:center; flex-wrap:wrap; }
.page-meta .num { font-family:var(--font-mono); font-feature-settings:'tnum'; color:var(--ink-2); font-weight:500; }
.page-meta .sep { color:var(--ink-disabled); }
.btn { display:inline-flex; align-items:center; gap:7px; height:34px; padding:0 14px; border-radius:var(--r-sm); border:1px solid var(--hairline); background:var(--surface); font-size:12.5px; font-weight:500; color:var(--ink); cursor:pointer; font-family:inherit; letter-spacing:-0.005em; }
.btn:hover { border-color:var(--ink-disabled); background:var(--sunken); }
.btn-primary { background:var(--accent); color:#fff; border-color:var(--accent); }
.btn-primary:hover { background:var(--accent-deep); border-color:var(--accent-deep); }
.btn-danger { color:var(--st-new); }
.btn-danger:hover { background:#FFE7E2; border-color:var(--st-new); color:#8E2516; }
.btn svg { width:13px; height:13px; stroke-width:1.7; }
/* SSO login screen */
.sso-shell { min-height:calc(100vh - 47px); display:grid; grid-template-columns:1fr 1fr; }
.sso-brand { background:var(--side-bg); color:#fff; padding:56px 60px; display:flex; flex-direction:column; justify-content:space-between; }
.sso-brand .head { display:flex; align-items:center; gap:10px; font-weight:600; font-size:16px; }
.sso-brand .head .mark { width:24px; height:24px; border-radius:5px; background:#fff; display:inline-flex; align-items:center; justify-content:center; overflow:hidden; }
.sso-brand .head .mark svg { width:100%; height:100%; }
.sso-brand .head .dot { color:var(--side-icon-act); }
.sso-brand .head .admin-tag { font-family:var(--font-mono); font-size:10px; letter-spacing:0.06em; padding:2px 6px; border-radius:3px; background:var(--imp-red); color:#fff; margin-left:auto; font-weight:600; }
.sso-brand .body { font-size:30px; font-weight:500; font-variation-settings:'opsz' 28; letter-spacing:-0.02em; line-height:1.2; max-width:440px; }
.sso-brand .body em { color: var(--side-icon-act); font-style: normal; }
.sso-brand .foot { font-size:12px; color:#7A8C87; font-family:var(--font-mono); }
.sso-form { background:var(--bg); display:flex; align-items:center; justify-content:center; padding:40px 32px; }
.sso-card { width:100%; max-width:380px; display:flex; flex-direction:column; gap:18px; }
.sso-card h1 { font-size:24px; font-weight:600; font-variation-settings:'opsz' 24; letter-spacing:-0.018em; margin:0 0 6px; line-height:1.2; }
.sso-card p { font-size:12.5px; color:var(--ink-3); line-height:1.5; margin:0; }
.sso-button {
display:flex; align-items:center; justify-content:center; gap:8px;
width:100%;
height:48px; padding:0 18px;
border:1px solid var(--ink); border-radius:var(--r-sm);
background:var(--ink); color:#fff;
font-size:13.5px; font-weight:500;
cursor:pointer; font-family:inherit;
letter-spacing:-0.005em;
}
.sso-button:hover { background:#000; }
.sso-button .y-ico {
width:20px; height:20px;
background:#FF0000; color:#fff;
border-radius:50%;
display:inline-flex; align-items:center; justify-content:center;
font-weight:700; font-size:11px;
font-family:Inter,sans-serif;
}
.sso-fallback { font-size:11.5px; color:var(--ink-3); text-align:center; }
.sso-fallback a { color:var(--accent); font-weight:500; }
.sso-fallback a:hover { text-decoration:underline; }
/* Tenants table */
.t-controls { display:flex; align-items:center; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
.search-input { display:inline-flex; align-items:center; gap:8px; flex:1; min-width:240px; height:34px; padding:0 12px; border:1px solid var(--hairline); border-radius:var(--r-sm); background:var(--surface); }
.search-input svg { width:13px; height:13px; color:var(--ink-3); }
.search-input input { flex:1; min-width:0; border:none; outline:none; background:none; font-family:inherit; font-size:13px; color:var(--ink); }
.search-input input::placeholder { color:var(--ink-3); }
.fbtn { height:34px; padding:0 12px; border:1px solid var(--hairline); border-radius:var(--r-sm); background:var(--surface); font-family:inherit; font-size:12px; color:var(--ink-2); cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.fbtn:hover { border-color:var(--ink-disabled); }
.fbtn svg { width:12px; height:12px; color:var(--ink-3); }
.tbl-wrap { background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-md); overflow:hidden; }
.tbl { width:100%; border-collapse:collapse; font-size:12.5px; }
.tbl thead th { text-align:left; font-size:10.5px; font-weight:600; color:var(--ink-2); padding:10px 14px; background:var(--sunken); border-bottom:1px solid var(--hairline); white-space:nowrap; letter-spacing:0.005em; }
.tbl thead th.num { text-align:right; }
.tbl tbody tr { border-bottom:1px solid var(--hairline-soft); cursor:pointer; }
.tbl tbody tr:last-child { border-bottom:none; }
.tbl tbody tr:hover { background:var(--sunken); }
.tbl tbody td { padding:10px 14px; vertical-align:middle; }
.tbl .t-name { font-weight:500; color:var(--ink); }
.tbl .t-name .sub { display:block; font-size:11px; color:var(--ink-3); margin-top:2px; font-family:var(--font-mono); font-feature-settings:'tnum'; }
.tbl .t-balance, .tbl .t-today, .tbl .t-mr { font-family:var(--font-mono); font-feature-settings:'tnum'; text-align:right; }
.tbl .t-balance.low { color:var(--st-new); font-weight:500; }
.tbl .t-since { font-family:var(--font-mono); font-feature-settings:'tnum'; font-size:11px; color:var(--ink-3); white-space:nowrap; }
.chip { display:inline-flex; align-items:center; gap:6px; font-size:11.5px; font-weight:500; }
.chip .dot { width:6px; height:6px; border-radius:50%; position:relative; }
.chip .dot::after { content:''; position:absolute; inset:-1px; border-radius:50%; border:1px solid rgba(10,19,25,0.10); }
.chip-active .dot { background:var(--st-quote); }
.chip-trial .dot { background:var(--st-paid); }
.chip-overdue .dot { background:var(--st-new); }
.chip-suspended .dot { background:var(--ink-disabled); }
/* Tenant card */
.tc-row { display:grid; grid-template-columns:1fr 360px; gap:16px; }
.tc-main { display:flex; flex-direction:column; gap:14px; }
.tc-aside { display:flex; flex-direction:column; gap:14px; }
.tc-head {
background:var(--surface); border:1px solid var(--hairline);
border-radius:var(--r-md); padding:22px 24px;
}
.tc-name { font-size:24px; font-weight:600; font-variation-settings:'opsz' 24; letter-spacing:-0.018em; margin:0 0 6px; }
.tc-meta { font-size:12.5px; color:var(--ink-3); display:flex; gap:12px; flex-wrap:wrap; }
.tc-meta .id { font-family:var(--font-mono); color:var(--accent); font-weight:600; }
.tc-meta .sep { color:var(--ink-disabled); }
.tc-actions { display:flex; gap:8px; margin-top:14px; flex-wrap:wrap; }
.tc-actions .imp { background:var(--imp-red); color:#fff; border-color:var(--imp-red); }
.tc-actions .imp:hover { background:#8E2516; border-color:#8E2516; }
.tc-section { background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-md); padding:18px 22px; }
.tc-section h2 { font-size:13px; font-weight:600; color:var(--ink-3); letter-spacing:0.005em; text-transform:uppercase; margin:0 0 12px; }
.kv-grid { display:grid; grid-template-columns:120px 1fr; gap:9px 14px; font-size:13px; }
.kv-grid .k { color:var(--ink-3); font-size:12px; }
.kv-grid .v { color:var(--ink); }
.kv-grid .v.mono { font-family:var(--font-mono); font-feature-settings:'tnum'; font-size:12px; }
.adj-form { display:grid; grid-template-columns:120px 1fr auto; gap:8px; align-items:center; margin-bottom:8px; }
.adj-form .input { height:34px; padding:0 10px; border:1px solid var(--hairline); border-radius:var(--r-sm); font-family:var(--font-mono); font-size:13px; }
.timeline-mini { display:flex; flex-direction:column; gap:12px; padding-left:16px; position:relative; }
.timeline-mini::before { content:''; position:absolute; left:5px; top:6px; bottom:6px; width:1px; background:var(--hairline); }
.tm-item { position:relative; }
.tm-item::before { content:''; position:absolute; left:-16px; top:4px; width:9px; height:9px; border-radius:50%; background:var(--surface); border:1.5px solid var(--ink-disabled); }
.tm-item.acc::before { background:var(--accent); border-color:var(--accent); }
.tm-item.warn::before { background:var(--st-call); border-color:var(--st-call); }
.tm-item.dang::before { background:var(--st-new); border-color:var(--st-new); }
.tm-when { font-family:var(--font-mono); font-size:10.5px; color:var(--ink-3); }
.tm-text { font-size:12px; color:var(--ink); margin-top:2px; line-height:1.45; }
/* Incidents */
.inc-row { display:grid; grid-template-columns:auto 100px 1fr 120px auto; gap:14px; padding:11px 18px; border-bottom:1px solid var(--hairline-soft); align-items:center; font-size:12.5px; }
.inc-row:last-child { border-bottom:none; }
.inc-row:hover { background:var(--sunken); cursor:pointer; }
.inc-id { font-family:var(--font-mono); font-feature-settings:'tnum'; font-size:11px; color:var(--accent); font-weight:500; }
.inc-when { font-family:var(--font-mono); font-feature-settings:'tnum'; font-size:11.5px; color:var(--ink-3); }
.inc-title { color:var(--ink); }
.inc-title .scope { display:block; font-size:11px; color:var(--ink-3); margin-top:2px; }
.inc-tenant { font-size:11.5px; color:var(--ink-2); }
.inc-sev { padding:2px 8px; border-radius:100px; font-size:10.5px; font-weight:600; letter-spacing:0.04em; font-family:var(--font-mono); }
.inc-sev.high { background:#FFE7E2; color:#8E2516; }
.inc-sev.med { background:#FFF4DD; color:#7B4D00; }
.inc-sev.low { background:var(--accent-tint); color:var(--accent-deep); }
/* System cards */
.sys-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:14px; }
.sys-card { background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-md); padding:18px 20px; cursor:pointer; }
.sys-card:hover { border-color:var(--ink-disabled); }
.sys-card .sc-h { display:flex; align-items:center; gap:10px; margin-bottom:8px; }
.sys-card .sc-ico { width:30px; height:30px; border-radius:var(--r-sm); background:var(--bg); display:inline-flex; align-items:center; justify-content:center; color:var(--accent); }
.sys-card .sc-ico svg { width:14px; height:14px; stroke-width:1.7; }
.sys-card .sc-name { font-size:14px; font-weight:600; letter-spacing:-0.012em; color:var(--ink); }
.sys-card .sc-desc { font-size:12px; color:var(--ink-3); line-height:1.45; }
.sys-card .sc-meta { font-size:11px; color:var(--ink-3); margin-top:10px; font-family:var(--font-mono); font-feature-settings:'tnum'; letter-spacing:-0.005em; }
.sys-card .sc-meta strong { color:var(--ink-2); font-weight:500; }
.tab-page { display:none; }
.tab-page.active { display:contents; }
@media (max-width:1100px) {
.app { grid-template-columns:56px 1fr; }
.side { padding:14px 6px; }
.brand-sub, .brand .brand-text, .nav-eyebrow, .nav-text, .nav-item:not(.active) .nav-count { display:none; }
.nav-item { justify-content:center; padding:0; }
.topbar { padding:0 16px; }
.content { padding:18px 18px 60px; }
.tc-row { grid-template-columns:1fr; }
.sys-grid { grid-template-columns:repeat(2, 1fr); }
.sso-shell { grid-template-columns:1fr; }
.sso-brand { padding:32px 24px; min-height:200px; }
}
@media (max-width:768px) {
.app { grid-template-columns:1fr; }
.side { display:none; }
.topbar .crumb span:first-child { display:none; }
.sys-grid { grid-template-columns:1fr; }
.tbl thead { display:none; }
.tbl, .tbl tbody, .tbl tr, .tbl td { display:block; width:100%; }
.tbl tbody tr { padding:12px; border:1px solid var(--hairline-soft); border-radius:var(--r-sm); margin-bottom:8px; }
.tbl tbody td { padding:3px 0; border:none; }
.inc-row { grid-template-columns:1fr; }
}
</style>
</head>
<body>
<nav class="review-bar" aria-label="Состояние админ-экрана (только для review)">
<span class="label">PREVIEW · ADMIN</span>
<div class="tabs" role="tablist">
<button type="button" class="tab active" data-tab="login" role="tab" aria-selected="true">SSO Вход</button>
<button type="button" class="tab" data-tab="tenants" role="tab" aria-selected="false">Тенанты</button>
<button type="button" class="tab" data-tab="tenant-card" role="tab" aria-selected="false">Карточка тенанта</button>
<button type="button" class="tab" data-tab="impersonation" role="tab" aria-selected="false">Импersonation-режим</button>
<button type="button" class="tab" data-tab="incidents" role="tab" aria-selected="false">Инциденты</button>
<button type="button" class="tab" data-tab="system" role="tab" aria-selected="false">Система</button>
</div>
</nav>
<!-- ===== ADMIN/LOGIN — SSO ===== -->
<section id="page-login" class="tab-page active">
<div class="sso-shell">
<aside class="sso-brand" aria-label="Брендинг">
<div class="head">
<span class="mark"><svg viewBox="0 0 48 48"><path d="M16 14 L16 34 L32 34" stroke="#012019" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="32" cy="34" r="3.5" fill="#0F6E56"/></svg></span>
<span>Лидерра<span class="dot">.</span></span>
<span class="admin-tag">ADMIN</span>
</div>
<div class="body">Операторская <em>SaaS-инструмент</em>.<br>Управление тенантами, биллингом, инцидентами.</div>
<div class="foot">v8 Forest · ограниченный доступ · все действия логируются в saas_admin_audit_log</div>
</aside>
<main class="sso-form">
<div class="sso-card">
<h1>Вход в админку</h1>
<p>SSO через Yandex 360 — основной путь. 2FA-fallback в крайнем случае.</p>
<button type="button" class="sso-button">
<span class="y-ico">Я</span>
Войти через Yandex 360
</button>
<div style="display:flex;align-items:center;gap:12px;margin:4px 0;color:var(--ink-3);font-size:11px"><span style="flex:1;height:1px;background:var(--hairline)"></span>или<span style="flex:1;height:1px;background:var(--hairline)"></span></div>
<button type="button" class="btn" style="height:42px;justify-content:center;width:100%">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
Локальный пароль + 2FA
</button>
<div class="sso-fallback">
Лимит 5 попыток / 15 минут · capture после 2 неудач · email при новом устройстве. <a href="#">Документация</a>
</div>
</div>
</main>
</div>
</section>
<!-- ===== ADMIN/TENANTS — list ===== -->
<section id="page-tenants" class="tab-page">
<div class="app">
<aside class="side" aria-label="Главное меню">
<div class="brand">
<span class="brand-mark"><svg viewBox="0 0 48 48"><path d="M16 14 L16 34 L32 34" stroke="#012019" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="32" cy="34" r="3.5" fill="#0F6E56"/></svg></span>
<span>Лидерра<span class="brand-dot">.</span></span>
</div>
<div class="brand-sub">ADMIN</div>
<nav class="nav">
<div class="nav-item active"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/></svg><span class="nav-text">Тенанты</span><span class="nav-count">142</span></div>
<div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="6" width="18" height="13" rx="1"/></svg><span class="nav-text">Биллинг</span></div>
<div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg><span class="nav-text">Инциденты</span><span class="nav-count">3</span></div>
<div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/></svg><span class="nav-text">Система</span></div>
</nav>
</aside>
<div class="main">
<div class="topbar">
<div class="crumb"><span>Админка</span><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></svg><strong>Тенанты</strong></div>
<div class="topbar-spacer"></div>
<span class="user-chip"><span class="ava">АО</span><span class="uname">Админ Оператор</span></span>
</div>
<main class="content">
<header class="page-h">
<div>
<h1 class="page-title">Тенанты</h1>
<div class="page-meta">
<span><span class="num">142</span> всего</span><span class="sep">·</span>
<span><span class="num">128</span> активны</span><span class="sep">·</span>
<span><span class="num">9</span> trial</span><span class="sep">·</span>
<span><span class="num">5</span> просрочка</span><span class="sep">·</span>
<span>выручка месяц <span class="num">1 248 600 ₽</span></span>
</div>
</div>
<div style="display:flex;gap:8px"><button type="button" class="btn"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7,10 12,15 17,10"/></svg>Экспорт</button></div>
</header>
<div class="t-controls">
<label class="search-input"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg><input type="search" placeholder="ИНН, юр. лицо, email админа…" aria-label="Поиск тенантов"></label>
<button type="button" class="fbtn"><span style="color:var(--ink-3)">Статус:</span><strong>Все</strong><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></svg></button>
<button type="button" class="fbtn"><span style="color:var(--ink-3)">Тариф:</span><strong>Все</strong><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></svg></button>
<button type="button" class="fbtn"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M22 3H2l8 9.46V19l4 2v-8.54L22 3z"/></svg>Ещё</button>
</div>
<div class="tbl-wrap">
<table class="tbl">
<thead><tr><th scope="col">Тенант</th><th scope="col">Статус</th><th scope="col">Тариф</th><th class="num" scope="col">Баланс ₽</th><th class="num" scope="col">Желаем×факт сегодня</th><th class="num" scope="col">MRR</th><th scope="col">Активность</th></tr></thead>
<tbody>
<tr><td class="t-name">Окна Москва ООО<span class="sub">ИНН 7724444444</span></td><td><span class="chip chip-active"><span class="dot"></span>Активен</span></td><td>Команда</td><td class="t-balance">14 250</td><td class="t-today">12 × 11</td><td class="t-mr">990</td><td class="t-since">28 мин назад</td></tr>
<tr><td class="t-name">Натяжные потолки СПб<span class="sub">ИНН 7805123456</span></td><td><span class="chip chip-active"><span class="dot"></span>Активен</span></td><td>Команда</td><td class="t-balance">38 100</td><td class="t-today">8 × 14</td><td class="t-mr">990</td><td class="t-since">14 мин назад</td></tr>
<tr><td class="t-name">Кухни на заказ Екб<span class="sub">ИНН 6671987654</span></td><td><span class="chip chip-active"><span class="dot"></span>Активен</span></td><td>Pro</td><td class="t-balance">112 800</td><td class="t-today">5 × 6</td><td class="t-mr">2 990</td><td class="t-since">1 ч назад</td></tr>
<tr><td class="t-name">Ремонт под ключ<span class="sub">ИНН 5024333222</span></td><td><span class="chip chip-trial"><span class="dot"></span>Trial · 4 дня</span></td><td>Trial</td><td class="t-balance">450</td><td class="t-today">3 × 0</td><td class="t-mr" style="color:var(--ink-3)"></td><td class="t-since">3 ч назад</td></tr>
<tr><td class="t-name">Двери Премиум<span class="sub">ИНН 7732111000</span></td><td><span class="chip chip-overdue"><span class="dot"></span>Просрочка 3 дня</span></td><td>Команда</td><td class="t-balance low">1 200</td><td class="t-today">0 × 0</td><td class="t-mr">990</td><td class="t-since">2 дня</td></tr>
<tr><td class="t-name">Оконные системы РФ<span class="sub">ИНН 7707654321</span></td><td><span class="chip chip-suspended"><span class="dot"></span>Приостановлен</span></td><td>Start</td><td class="t-balance" style="color:var(--ink-disabled)">0</td><td class="t-today">0 × 0</td><td class="t-mr" style="color:var(--ink-3)"></td><td class="t-since">7 дней</td></tr>
<tr><td class="t-name">Кухонная мебель Спб<span class="sub">ИНН 7813222333</span></td><td><span class="chip chip-active"><span class="dot"></span>Активен</span></td><td>Enterprise</td><td class="t-balance">486 200</td><td class="t-today">28 × 31</td><td class="t-mr">9 990</td><td class="t-since">8 мин назад</td></tr>
</tbody>
</table>
</div>
</main>
</div>
</div>
</section>
<!-- ===== ADMIN/TENANT-CARD ===== -->
<section id="page-tenant-card" class="tab-page">
<div class="app">
<aside class="side"><div class="brand"><span class="brand-mark"><svg viewBox="0 0 48 48"><path d="M16 14 L16 34 L32 34" stroke="#012019" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="32" cy="34" r="3.5" fill="#0F6E56"/></svg></span><span>Лидерра<span class="brand-dot">.</span></span></div><div class="brand-sub">ADMIN</div><nav class="nav"><div class="nav-item active"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="9" cy="7" r="4"/><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/></svg><span class="nav-text">Тенанты</span><span class="nav-count">142</span></div><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="6" width="18" height="13" rx="1"/></svg><span class="nav-text">Биллинг</span></div><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg><span class="nav-text">Инциденты</span><span class="nav-count">3</span></div><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/></svg><span class="nav-text">Система</span></div></nav></aside>
<div class="main">
<div class="topbar">
<div class="crumb"><span>Админка</span><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></svg><a>Тенанты</a><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></svg><strong>Окна Москва ООО</strong></div>
<div class="topbar-spacer"></div>
<span class="user-chip"><span class="ava">АО</span><span class="uname">Админ Оператор</span></span>
</div>
<main class="content">
<div class="tc-row">
<div class="tc-main">
<header class="tc-head">
<h1 class="tc-name">Окна Москва ООО</h1>
<div class="tc-meta">
<span class="id">#TNT-0042</span>
<span>ИНН 7724444444 / КПП 772401001</span>
<span class="sep">·</span>
<span>с 12.04.2026 (3 недели)</span>
<span class="sep">·</span>
<span><span class="chip chip-active"><span class="dot"></span>Активен</span></span>
</div>
<div class="tc-actions">
<button type="button" class="btn"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M12 20h9M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4z"/></svg>Редактировать</button>
<button type="button" class="btn"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7,10 12,15 17,10"/></svg>Корректировать баланс</button>
<button type="button" class="btn imp"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="7" r="4"/><path d="M2 21v-2a4 4 0 0 1 4-4h12a4 4 0 0 1 4 4v2"/></svg>Войти как клиент</button>
<button type="button" class="btn btn-danger"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/></svg>Удалить (152-ФЗ)</button>
</div>
</header>
<section class="tc-section">
<h2>Профиль</h2>
<div class="kv-grid">
<span class="k">Юр. лицо</span><span class="v">ООО «Окна Москва»</span>
<span class="k">Юр. адрес</span><span class="v">115093, Москва, ул. Большая Серпуховская, 32 стр. 1, оф. 405</span>
<span class="k">Расчётный счёт</span><span class="v mono">40702810400000000123 · ПАО «Сбербанк»</span>
<span class="k">Email админа</span><span class="v">ivan.petrov@example.ru</span>
<span class="k">Телефон</span><span class="v mono">+7 (495) 482-91-22</span>
<span class="k">Тариф</span><span class="v">Команда (990 ₽/мес) · автопродление</span>
<span class="k">Активные проекты</span><span class="v mono">3 / 10</span>
<span class="k">Менеджеры</span><span class="v mono">4</span>
</div>
</section>
<section class="tc-section">
<h2>Корректировка баланса</h2>
<div class="adj-form">
<input type="text" class="input" placeholder="Сумма" value="+ 5 000">
<input type="text" class="input" placeholder="Причина (обязательно)" value="Возврат по обращению ticket-2841: ошибка дублирования лида">
<button type="button" class="btn btn-primary">Применить</button>
</div>
<div style="font-size:11px;color:var(--ink-3);margin-top:6px">Запись в saas_admin_audit_log будет создана автоматически. Действие обратимо в течение 24 часов.</div>
</section>
</div>
<aside class="tc-aside">
<section class="tc-section">
<h2>Баланс и активность</h2>
<div class="kv-grid">
<span class="k">Баланс ₽</span><span class="v mono" style="color:var(--accent);font-weight:600">14 250 ₽</span>
<span class="k">Лидов запас</span><span class="v mono">285</span>
<span class="k">Желаем сегодня</span><span class="v mono">12</span>
<span class="k">Факт сегодня</span><span class="v mono">11</span>
<span class="k">MRR</span><span class="v mono">990 ₽</span>
<span class="k">LTV (3 нед.)</span><span class="v mono">2 970 ₽</span>
</div>
</section>
<section class="tc-section">
<h2>Журнал действий</h2>
<div class="timeline-mini">
<div class="tm-item warn"><div class="tm-when">07.05 · 14:48</div><div class="tm-text">Админ <strong>Иван Оператор</strong> вошёл как клиент (impersonation, 4 мин)</div></div>
<div class="tm-item acc"><div class="tm-when">06.05 · 22:06</div><div class="tm-text">Пополнение через ЮKassa: + 10 000 ₽</div></div>
<div class="tm-item dang"><div class="tm-when">04.05 · 16:42</div><div class="tm-text">Попытка пополнения через банковский перевод — отклонено</div></div>
<div class="tm-item"><div class="tm-when">12.04 · 09:32</div><div class="tm-text">Регистрация · trial 7 дней</div></div>
</div>
</section>
</aside>
</div>
</main>
</div>
</div>
</section>
<!-- ===== IMPERSONATION MODE ===== -->
<section id="page-impersonation" class="tab-page">
<div class="imp-banner" role="status">
<span style="display:inline-flex;align-items:center;gap:8px">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.7"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12" y2="17"/></svg>
<strong>IMPERSONATION</strong>
<span style="opacity:0.85">Вы вошли как <strong>Окна Москва ООО / Иван Петров</strong> · действия логируются как admin · 04:32</span>
</span>
<button type="button">Выйти из режима</button>
</div>
<div class="app">
<aside class="side" aria-label="Главное меню">
<div class="brand"><span class="brand-mark"><svg viewBox="0 0 48 48"><path d="M16 14 L16 34 L32 34" stroke="#012019" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="32" cy="34" r="3.5" fill="#0F6E56"/></svg></span><span>Лидерра<span class="brand-dot">.</span></span></div>
<nav class="nav">
<div class="nav-eyebrow">Работа</div>
<div class="nav-item active"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg><span class="nav-text">Дашборд</span></div>
<div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M3 6h18M6 12h12M9 18h6"/></svg><span class="nav-text">Сделки</span><span class="nav-count">247</span></div>
<div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="3" width="6" height="18"/></svg><span class="nav-text">Канбан</span></div>
</nav>
</aside>
<div class="main">
<div class="topbar"><div class="crumb"><strong>Дашборд</strong> <span style="color:var(--imp-red);font-weight:600;font-size:11.5px;font-family:var(--font-mono)">· через клиента</span></div><div class="topbar-spacer"></div><span class="user-chip"><span class="ava" style="background:var(--imp-red)">АО</span><span class="uname">Админ → ИП</span></span></div>
<main class="content"><header class="page-h"><div><h1 class="page-title">Доброе утро, Иван</h1><div class="page-meta"><span><span class="num" style="color:var(--accent);font-weight:600">+3</span> новых лида с утра</span></div></div></header>
<p style="font-size:13px;color:var(--ink-3);line-height:1.6;max-width:600px">Это дашборд клиента в режиме <strong style="color:var(--imp-red)">impersonation</strong>. Все действия фиксируются в saas_admin_audit_log с пометкой импersonator + причина (обязательно при входе). Выход из режима через красный баннер вверху.</p>
</main>
</div>
</div>
</section>
<!-- ===== INCIDENTS ===== -->
<section id="page-incidents" class="tab-page">
<div class="app">
<aside class="side"><div class="brand"><span class="brand-mark"><svg viewBox="0 0 48 48"><path d="M16 14 L16 34 L32 34" stroke="#012019" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="32" cy="34" r="3.5" fill="#0F6E56"/></svg></span><span>Лидерра<span class="brand-dot">.</span></span></div><div class="brand-sub">ADMIN</div><nav class="nav"><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="9" cy="7" r="4"/></svg><span class="nav-text">Тенанты</span></div><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="6" width="18" height="13" rx="1"/></svg><span class="nav-text">Биллинг</span></div><div class="nav-item active"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg><span class="nav-text">Инциденты</span><span class="nav-count">3</span></div><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/></svg><span class="nav-text">Система</span></div></nav></aside>
<div class="main">
<div class="topbar"><div class="crumb"><span>Админка</span><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></svg><strong>Журнал инцидентов</strong></div><div class="topbar-spacer"></div><span class="user-chip"><span class="ava">АО</span><span class="uname">Админ Оператор</span></span></div>
<main class="content">
<header class="page-h"><div><h1 class="page-title">Журнал инцидентов</h1><div class="page-meta"><span><span class="num">3</span> открытых</span><span class="sep">·</span><span><span class="num">87</span> за последние 30 дней</span><span class="sep">·</span><span>read-only для compliance</span></div></div></header>
<div class="tbl-wrap">
<div class="inc-row" style="background:var(--sunken);font-size:10.5px;font-weight:600;color:var(--ink-2);padding:10px 18px;border-bottom:1px solid var(--hairline)"><span>ID</span><span>Когда</span><span>Описание</span><span>Тенант</span><span>Severity</span></div>
<div class="inc-row"><span class="inc-id">INC-0034</span><span class="inc-when">07.05 · 14:23</span><span class="inc-title">Webhook timeout 5 раз подряд<span class="scope">endpoint /api/lead-in · TG-бот тенанта</span></span><span class="inc-tenant">Окна Москва ООО</span><span class="inc-sev high">HIGH</span></div>
<div class="inc-row"><span class="inc-id">INC-0033</span><span class="inc-when">07.05 · 09:14</span><span class="inc-title">SMS-шлюз timeout > 400ms<span class="scope">SMSC.RU деградация · 96.4%</span></span><span class="inc-tenant">Все тенанты</span><span class="inc-sev med">MED</span></div>
<div class="inc-row"><span class="inc-id">INC-0032</span><span class="inc-when">06.05 · 22:48</span><span class="inc-title">Дублирование лида<span class="scope">Я.Директ webhook прислал дубль за 18 секунд</span></span><span class="inc-tenant">Натяжные потолки СПб</span><span class="inc-sev low">LOW</span></div>
<div class="inc-row"><span class="inc-id">INC-0031</span><span class="inc-when">06.05 · 16:01</span><span class="inc-title">Failed Stripe payment retry<span class="scope">3 попытки за 7 дней · перевод в manual</span></span><span class="inc-tenant">Двери Премиум</span><span class="inc-sev med">MED</span></div>
<div class="inc-row"><span class="inc-id">INC-0030</span><span class="inc-when">05.05 · 11:32</span><span class="inc-title">RLS bypass attempt<span class="scope">tenant_id mismatch на /api/deals — отбито</span></span><span class="inc-tenant">Кухни на заказ Екб</span><span class="inc-sev high">HIGH</span></div>
<div class="inc-row"><span class="inc-id">INC-0029</span><span class="inc-when">05.05 · 08:22</span><span class="inc-title">Бэкап БД задержка<span class="scope">snapshot задержался на 38 минут — без потерь</span></span><span class="inc-tenant">Все тенанты</span><span class="inc-sev low">LOW</span></div>
</div>
</main>
</div>
</div>
</section>
<!-- ===== SYSTEM ===== -->
<section id="page-system" class="tab-page">
<div class="app">
<aside class="side"><div class="brand"><span class="brand-mark"><svg viewBox="0 0 48 48"><path d="M16 14 L16 34 L32 34" stroke="#012019" stroke-width="4.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/><circle cx="32" cy="34" r="3.5" fill="#0F6E56"/></svg></span><span>Лидерра<span class="brand-dot">.</span></span></div><div class="brand-sub">ADMIN</div><nav class="nav"><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="9" cy="7" r="4"/></svg><span class="nav-text">Тенанты</span></div><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="6" width="18" height="13" rx="1"/></svg><span class="nav-text">Биллинг</span></div><div class="nav-item"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg><span class="nav-text">Инциденты</span><span class="nav-count">3</span></div><div class="nav-item active"><svg class="nav-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/></svg><span class="nav-text">Система</span></div></nav></aside>
<div class="main">
<div class="topbar"><div class="crumb"><span>Админка</span><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></svg><strong>Система</strong></div><div class="topbar-spacer"></div><span class="user-chip"><span class="ava">АО</span><span class="uname">Админ Оператор</span></span></div>
<main class="content">
<header class="page-h"><div><h1 class="page-title">Системные настройки</h1><div class="page-meta"><span>super_admin доступ</span><span class="sep">·</span><span>все изменения логируются</span></div></div></header>
<div class="sys-grid">
<button type="button" class="sys-card"><div class="sc-h"><span class="sc-ico"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M12 1v6M12 17v6M4.22 4.22l4.24 4.24M15.54 15.54l4.24 4.24M1 12h6M17 12h6M4.22 19.78l4.24-4.24M15.54 8.46l4.24-4.24"/></svg></span><span class="sc-name">system_settings</span></div><div class="sc-desc">Глобальные параметры платформы: лимиты, таймауты, фичефлаги</div><div class="sc-meta"><strong>27</strong> параметров · обновлено 3 часа назад</div></button>
<button type="button" class="sys-card"><div class="sc-h"><span class="sc-ico"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5z"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg></span><span class="sc-name">tariff_plans</span></div><div class="sc-desc">Тарифы Start/Basic/Pro/Enterprise — цена, лимиты, фичи</div><div class="sc-meta"><strong>4</strong> тарифа · последнее изменение 21.04</div></button>
<button type="button" class="sys-card"><div class="sc-h"><span class="sc-ico"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M3 7v13h18V7M3 7l3-4h12l3 4M3 7h18"/></svg></span><span class="sc-name">legal_entities</span></div><div class="sc-desc">Юр. лица оператора — для счетов и УПД</div><div class="sc-meta"><strong>1</strong> активно · ИП Сидоров А.А.</div></button>
<button type="button" class="sys-card"><div class="sc-h"><span class="sc-ico"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="6" width="18" height="13" rx="1"/><path d="M3 10h18M7 15h3"/></svg></span><span class="sc-name">payment_gateways</span></div><div class="sc-desc">ЮKassa, Stripe, банковский перевод — статус и комиссии</div><div class="sc-meta"><strong>3</strong> активных · ЮKassa primary</div></button>
<button type="button" class="sys-card"><div class="sc-h"><span class="sc-ico"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M21 2L13 10M16 2h5v5"/><path d="M21 13v5a2 2 0 0 1-2 2h-14a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5"/></svg></span><span class="sc-name">webhook_log</span></div><div class="sc-desc">Все outbound и inbound webhook-события за 30 дней</div><div class="sc-meta"><strong>284 612</strong> событий · 99.97% uptime</div></button>
<button type="button" class="sys-card"><div class="sc-h"><span class="sc-ico"><svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></span><span class="sc-name">auth_log</span></div><div class="sc-desc">Все вход/выход события — клиенты, админы, impersonation</div><div class="sc-meta"><strong>4 821</strong> событий за 7 дней</div></button>
</div>
</main>
</div>
</div>
</section>
<script>
const tabs = Array.from(document.querySelectorAll('.review-bar .tab'));
const pages = Array.from(document.querySelectorAll('.tab-page'));
function setTab(id) {
tabs.forEach(t => {
const isA = t.dataset.tab === id;
t.classList.toggle('active', isA);
t.setAttribute('aria-selected', isA ? 'true' : 'false');
});
pages.forEach(p => p.classList.toggle('active', p.id === 'page-' + id));
}
tabs.forEach(t => t.addEventListener('click', () => setTab(t.dataset.tab)));
</script>
</body>
</html>